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:
|
script:
|
||||||
- ./autogen.sh
|
- ./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
|
||||||
- make install -s
|
- make install -s
|
||||||
- make xref
|
- make xref
|
||||||
|
17
configure.ac
17
configure.ac
@ -109,10 +109,10 @@ AC_ARG_ENABLE(mssql,
|
|||||||
esac],[db_type=generic])
|
esac],[db_type=generic])
|
||||||
|
|
||||||
AC_ARG_ENABLE(all,
|
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
|
[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 ;;
|
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 riak=false redis=false elixir=false stun=false sip=false debug=false tools=false ;;
|
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) ;;
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||||
esac],[])
|
esac],[])
|
||||||
|
|
||||||
@ -172,14 +172,6 @@ AC_ARG_ENABLE(zlib,
|
|||||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
|
||||||
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
|
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_ARG_ENABLE(redis,
|
||||||
[AC_HELP_STRING([--enable-redis], [enable Redis support (default: no)])],
|
[AC_HELP_STRING([--enable-redis], [enable Redis support (default: no)])],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
@ -275,7 +267,7 @@ if test "$sqlite" = "true"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
enabled_backends=""
|
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 eval test x\${$backend} = xtrue; then
|
||||||
if test "x$enabled_backends" = "x"; then
|
if test "x$enabled_backends" = "x"; then
|
||||||
enabled_backends=$backend
|
enabled_backends=$backend
|
||||||
@ -296,7 +288,6 @@ AC_SUBST(pgsql)
|
|||||||
AC_SUBST(sqlite)
|
AC_SUBST(sqlite)
|
||||||
AC_SUBST(pam)
|
AC_SUBST(pam)
|
||||||
AC_SUBST(zlib)
|
AC_SUBST(zlib)
|
||||||
AC_SUBST(riak)
|
|
||||||
AC_SUBST(redis)
|
AC_SUBST(redis)
|
||||||
AC_SUBST(elixir)
|
AC_SUBST(elixir)
|
||||||
AC_SUBST(stun)
|
AC_SUBST(stun)
|
||||||
|
1
mix.exs
1
mix.exs
@ -107,7 +107,6 @@ defmodule Ejabberd.Mixfile do
|
|||||||
|
|
||||||
defp cond_deps do
|
defp cond_deps do
|
||||||
for {:true, dep} <- [{config(:sqlite), {:sqlite3, "~> 1.1"}},
|
for {:true, dep} <- [{config(:sqlite), {:sqlite3, "~> 1.1"}},
|
||||||
{config(:riak), {:riakc, "~> 2.4"}},
|
|
||||||
{config(:redis), {:eredis, "~> 1.0"}},
|
{config(:redis), {:eredis, "~> 1.0"}},
|
||||||
{config(:zlib), {:ezlib, "~> 1.0"}},
|
{config(:zlib), {:ezlib, "~> 1.0"}},
|
||||||
{config(:pam), {:epam, "~> 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_pgsql": {:hex, :p1_pgsql, "1.1.7", "ef64d34adbbe08258cc10b1532649446d8c086ff8663d44f430d837ec31a89f8", [:rebar3], [], "hexpm"},
|
||||||
"p1_utils": {:hex, :p1_utils, "1.0.15", "731f76ae1f31f4554afb2ae629cb5589d53bd13efc72b11f5a7c3b1242f91046", [:rebar3], [], "hexpm"},
|
"p1_utils": {:hex, :p1_utils, "1.0.15", "731f76ae1f31f4554afb2ae629cb5589d53bd13efc72b11f5a7c3b1242f91046", [:rebar3], [], "hexpm"},
|
||||||
"pkix": {:hex, :pkix, "1.0.2", "f618455c4edbcc7ebf8be5e655b269876fa36e890b806d18d8b2b708dfb1e583", [: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"},
|
"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"},
|
"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"},
|
"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"}}}},
|
{tag, "1.0.6"}}}},
|
||||||
{if_var_true, zlib, {ezlib, ".*", {git, "https://github.com/processone/ezlib",
|
{if_var_true, zlib, {ezlib, ".*", {git, "https://github.com/processone/ezlib",
|
||||||
{tag, "1.0.6"}}}},
|
{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
|
%% Elixir support, needed to run tests
|
||||||
{if_var_true, elixir, {elixir, ".*", {git, "https://github.com/elixir-lang/elixir",
|
{if_var_true, elixir, {elixir, ".*", {git, "https://github.com/elixir-lang/elixir",
|
||||||
{tag, {if_version_above, "17", "v1.4.4", "v1.1.1"}}}}},
|
{tag, {if_version_above, "17", "v1.4.4", "v1.1.1"}}}}},
|
||||||
@ -129,8 +127,6 @@
|
|||||||
{if_var_false, mysql, "(\".*mysql.*\":_/_)"},
|
{if_var_false, mysql, "(\".*mysql.*\":_/_)"},
|
||||||
{if_var_false, pgsql, "(\".*pgsql.*\":_/_)"},
|
{if_var_false, pgsql, "(\".*pgsql.*\":_/_)"},
|
||||||
{if_var_false, pam, "(\"epam\":_/_)"},
|
{if_var_false, pam, "(\"epam\":_/_)"},
|
||||||
{if_var_false, riak, "(\"riak.*\":_/_)"},
|
|
||||||
{if_var_true, riak, "(\"riak_object\":_/_)"},
|
|
||||||
{if_var_false, zlib, "(\"ezlib\":_/_)"},
|
{if_var_false, zlib, "(\"ezlib\":_/_)"},
|
||||||
{if_var_false, http, "(\"lhttpc\":_/_)"},
|
{if_var_false, http, "(\"lhttpc\":_/_)"},
|
||||||
{if_var_false, odbc, "(\"odbc\":_/_)"},
|
{if_var_false, odbc, "(\"odbc\":_/_)"},
|
||||||
|
@ -278,7 +278,7 @@ get_commands_spec() ->
|
|||||||
args_example = ["example.com"],
|
args_example = ["example.com"],
|
||||||
args = [{host, binary}], result = {res, rescode}},
|
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",
|
desc = "Import data from Prosody",
|
||||||
longdesc = "Note: this method requires ejabberd compiled with optional tools support "
|
longdesc = "Note: this method requires ejabberd compiled with optional tools support "
|
||||||
"and package must provide optional luerl dependency.",
|
"and package must provide optional luerl dependency.",
|
||||||
|
@ -901,7 +901,5 @@ import_start(_LServer, _) ->
|
|||||||
|
|
||||||
import(Server, {sql, _}, mnesia, <<"users">>, Fields) ->
|
import(Server, {sql, _}, mnesia, <<"users">>, Fields) ->
|
||||||
ejabberd_auth_mnesia:import(Server, Fields);
|
ejabberd_auth_mnesia:import(Server, Fields);
|
||||||
import(Server, {sql, _}, riak, <<"users">>, Fields) ->
|
|
||||||
ejabberd_auth_riak:import(Server, Fields);
|
|
||||||
import(_LServer, {sql, _}, sql, <<"users">>, _) ->
|
import(_LServer, {sql, _}, sql, <<"users">>, _) ->
|
||||||
ok.
|
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),
|
Opts1 = transform_register(Opts),
|
||||||
Opts2 = transform_s2s(Opts1),
|
Opts2 = transform_s2s(Opts1),
|
||||||
Opts3 = transform_listeners(Opts2),
|
Opts3 = transform_listeners(Opts2),
|
||||||
Opts4 = transform_sql(Opts3),
|
Opts5 = transform_sql(Opts3),
|
||||||
Opts5 = transform_riak(Opts4),
|
|
||||||
Opts6 = transform_shaper(Opts5),
|
Opts6 = transform_shaper(Opts5),
|
||||||
Opts7 = transform_s2s_out(Opts6),
|
Opts7 = transform_s2s_out(Opts6),
|
||||||
Opts8 = transform_acl(Opts7),
|
Opts8 = transform_acl(Opts7),
|
||||||
@ -412,17 +411,6 @@ transform_sql({odbc_pool_size, N}, Opts) ->
|
|||||||
transform_sql(Opt, Opts) ->
|
transform_sql(Opt, Opts) ->
|
||||||
[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
|
%%% modules
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -105,13 +105,6 @@
|
|||||||
-export([redis_server/0]).
|
-export([redis_server/0]).
|
||||||
-export([registration_timeout/0]).
|
-export([registration_timeout/0]).
|
||||||
-export([resource_conflict/0, resource_conflict/1]).
|
-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_life_time/0]).
|
||||||
-export([router_cache_missed/0]).
|
-export([router_cache_missed/0]).
|
||||||
-export([router_cache_size/0]).
|
-export([router_cache_size/0]).
|
||||||
@ -327,17 +320,17 @@ cluster_backend() ->
|
|||||||
cluster_nodes() ->
|
cluster_nodes() ->
|
||||||
ejabberd_config:get_option({cluster_nodes, global}).
|
ejabberd_config:get_option({cluster_nodes, global}).
|
||||||
|
|
||||||
-spec default_db() -> 'mnesia' | 'riak' | 'sql'.
|
-spec default_db() -> 'mnesia' | 'sql'.
|
||||||
default_db() ->
|
default_db() ->
|
||||||
default_db(global).
|
default_db(global).
|
||||||
-spec default_db(global | binary()) -> 'mnesia' | 'riak' | 'sql'.
|
-spec default_db(global | binary()) -> 'mnesia' | 'sql'.
|
||||||
default_db(Host) ->
|
default_db(Host) ->
|
||||||
ejabberd_config:get_option({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() ->
|
||||||
default_ram_db(global).
|
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) ->
|
default_ram_db(Host) ->
|
||||||
ejabberd_config:get_option({default_ram_db, Host}).
|
ejabberd_config:get_option({default_ram_db, Host}).
|
||||||
|
|
||||||
@ -735,34 +728,6 @@ resource_conflict() ->
|
|||||||
resource_conflict(Host) ->
|
resource_conflict(Host) ->
|
||||||
ejabberd_config:get_option({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().
|
-spec router_cache_life_time() -> 'infinity' | pos_integer().
|
||||||
router_cache_life_time() ->
|
router_cache_life_time() ->
|
||||||
ejabberd_config:get_option({router_cache_life_time, global}).
|
ejabberd_config:get_option({router_cache_life_time, global}).
|
||||||
|
@ -104,9 +104,9 @@ opt_type(cluster_backend) ->
|
|||||||
opt_type(cluster_nodes) ->
|
opt_type(cluster_nodes) ->
|
||||||
econf:list(econf:atom(), [unique]);
|
econf:list(econf:atom(), [unique]);
|
||||||
opt_type(default_db) ->
|
opt_type(default_db) ->
|
||||||
econf:enum([mnesia, riak, sql]);
|
econf:enum([mnesia, sql]);
|
||||||
opt_type(default_ram_db) ->
|
opt_type(default_ram_db) ->
|
||||||
econf:enum([mnesia, riak, sql, redis]);
|
econf:enum([mnesia, sql, redis]);
|
||||||
opt_type(define_macro) ->
|
opt_type(define_macro) ->
|
||||||
econf:any();
|
econf:any();
|
||||||
opt_type(disable_sasl_mechanisms) ->
|
opt_type(disable_sasl_mechanisms) ->
|
||||||
@ -280,20 +280,6 @@ opt_type(registration_timeout) ->
|
|||||||
econf:timeout(second, infinity);
|
econf:timeout(second, infinity);
|
||||||
opt_type(resource_conflict) ->
|
opt_type(resource_conflict) ->
|
||||||
econf:enum([setresource, closeold, closenew, acceptnew]);
|
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) ->
|
opt_type(router_cache_life_time) ->
|
||||||
econf:timeout(second, infinity);
|
econf:timeout(second, infinity);
|
||||||
opt_type(router_cache_missed) ->
|
opt_type(router_cache_missed) ->
|
||||||
@ -570,13 +556,6 @@ options() ->
|
|||||||
{redis_server, "localhost"},
|
{redis_server, "localhost"},
|
||||||
{registration_timeout, timer:seconds(600)},
|
{registration_timeout, timer:seconds(600)},
|
||||||
{resource_conflict, acceptnew},
|
{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,
|
{router_cache_life_time,
|
||||||
fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end},
|
fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end},
|
||||||
{router_cache_missed,
|
{router_cache_missed,
|
||||||
@ -702,13 +681,6 @@ globals() ->
|
|||||||
redis_queue_type,
|
redis_queue_type,
|
||||||
redis_server,
|
redis_server,
|
||||||
registration_timeout,
|
registration_timeout,
|
||||||
riak_cacertfile,
|
|
||||||
riak_password,
|
|
||||||
riak_pool_size,
|
|
||||||
riak_port,
|
|
||||||
riak_server,
|
|
||||||
riak_start_interval,
|
|
||||||
riak_username,
|
|
||||||
router_cache_life_time,
|
router_cache_life_time,
|
||||||
router_cache_missed,
|
router_cache_missed,
|
||||||
router_cache_size,
|
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.
|
MySQL should be accepting TCP connections on localhost:3306.
|
||||||
PostgreSQL should be accepting TCP connections on localhost:5432.
|
PostgreSQL should be accepting TCP connections on localhost:5432.
|
||||||
Redis should be accepting TCP connections on localhost:6379.
|
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
|
MySQL and PostgreSQL should grant full access to user 'ejabberd_test' with
|
||||||
password 'ejabberd_test' on database 'ejabberd_test'.
|
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:
|
Here is a quick setup example:
|
||||||
|
|
||||||
@ -25,27 +22,3 @@ $ mysql
|
|||||||
mysql> CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';
|
mysql> CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';
|
||||||
mysql> CREATE DATABASE ejabberd_test;
|
mysql> CREATE DATABASE ejabberd_test;
|
||||||
mysql> GRANT ALL ON ejabberd_test.* TO 'ejabberd_test'@'localhost';
|
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.
|
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.
|
attached to it.
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir test/docker/db/mysql/data
|
mkdir test/docker/db/mysql/data
|
||||||
mkdir test/docker/db/postgres/data
|
mkdir test/docker/db/postgres/data
|
||||||
mkdir test/docker/db/riak/data
|
|
||||||
(cd test/docker; docker-compose up)
|
(cd test/docker; docker-compose up)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -31,14 +30,6 @@ You can run tests with (from ejabberd repository root):
|
|||||||
make test
|
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
|
## Cleaning up the test environment
|
||||||
|
|
||||||
You can fully clean up the environment with:
|
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/mysql/data
|
||||||
rm -rf test/docker/db/postgres/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
|
container_name: ejabberd-redis
|
||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 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);
|
set_opt(server, ?LDAP_VHOST, Config);
|
||||||
do_init_per_group(extauth, Config) ->
|
do_init_per_group(extauth, Config) ->
|
||||||
set_opt(server, ?EXTAUTH_VHOST, 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) ->
|
do_init_per_group(s2s, Config) ->
|
||||||
ejabberd_config:set_option({s2s_use_starttls, ?COMMON_VHOST}, required),
|
ejabberd_config:set_option({s2s_use_starttls, ?COMMON_VHOST}, required),
|
||||||
ejabberd_config:set_option(ca_file, "ca.pem"),
|
ejabberd_config:set_option(ca_file, "ca.pem"),
|
||||||
@ -177,13 +168,6 @@ end_per_group(ldap, _Config) ->
|
|||||||
ok;
|
ok;
|
||||||
end_per_group(extauth, _Config) ->
|
end_per_group(extauth, _Config) ->
|
||||||
ok;
|
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) ->
|
end_per_group(component, _Config) ->
|
||||||
ok;
|
ok;
|
||||||
end_per_group(s2s, Config) ->
|
end_per_group(s2s, Config) ->
|
||||||
@ -379,28 +363,6 @@ no_db_tests() ->
|
|||||||
carbons_tests:single_cases(),
|
carbons_tests:single_cases(),
|
||||||
carbons_tests:master_slave_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 ->
|
db_tests(DB) when DB == mnesia; DB == redis ->
|
||||||
[{single_user, [sequence],
|
[{single_user, [sequence],
|
||||||
[test_register,
|
[test_register,
|
||||||
@ -519,8 +481,7 @@ groups() ->
|
|||||||
{redis, [sequence], db_tests(redis)},
|
{redis, [sequence], db_tests(redis)},
|
||||||
{mysql, [sequence], db_tests(mysql)},
|
{mysql, [sequence], db_tests(mysql)},
|
||||||
{pgsql, [sequence], db_tests(pgsql)},
|
{pgsql, [sequence], db_tests(pgsql)},
|
||||||
{sqlite, [sequence], db_tests(sqlite)},
|
{sqlite, [sequence], db_tests(sqlite)}].
|
||||||
{riak, [sequence], db_tests(riak)}].
|
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
[{group, ldap},
|
[{group, ldap},
|
||||||
@ -531,7 +492,6 @@ all() ->
|
|||||||
{group, pgsql},
|
{group, pgsql},
|
||||||
{group, sqlite},
|
{group, sqlite},
|
||||||
{group, extauth},
|
{group, extauth},
|
||||||
{group, riak},
|
|
||||||
{group, component},
|
{group, component},
|
||||||
{group, s2s},
|
{group, s2s},
|
||||||
stop_ejabberd].
|
stop_ejabberd].
|
||||||
@ -1113,16 +1073,3 @@ split(Data) ->
|
|||||||
(_) ->
|
(_) ->
|
||||||
true
|
true
|
||||||
end, re:split(Data, <<"\s">>)).
|
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.mysql.yml
|
||||||
- ejabberd.pgsql.yml
|
- ejabberd.pgsql.yml
|
||||||
- ejabberd.redis.yml
|
- ejabberd.redis.yml
|
||||||
- ejabberd.riak.yml
|
|
||||||
- ejabberd.sqlite.yml
|
- ejabberd.sqlite.yml
|
||||||
|
|
||||||
host_config:
|
host_config:
|
||||||
@ -15,7 +14,6 @@ host_config:
|
|||||||
mysql.localhost: MYSQL_CONFIG
|
mysql.localhost: MYSQL_CONFIG
|
||||||
mnesia.localhost: MNESIA_CONFIG
|
mnesia.localhost: MNESIA_CONFIG
|
||||||
redis.localhost: REDIS_CONFIG
|
redis.localhost: REDIS_CONFIG
|
||||||
riak.localhost: RIAK_CONFIG
|
|
||||||
ldap.localhost: LDAP_CONFIG
|
ldap.localhost: LDAP_CONFIG
|
||||||
extauth.localhost: EXTAUTH_CONFIG
|
extauth.localhost: EXTAUTH_CONFIG
|
||||||
localhost:
|
localhost:
|
||||||
@ -31,7 +29,6 @@ hosts:
|
|||||||
- pgsql.localhost
|
- pgsql.localhost
|
||||||
- extauth.localhost
|
- extauth.localhost
|
||||||
- ldap.localhost
|
- ldap.localhost
|
||||||
- riak.localhost
|
|
||||||
- sqlite.localhost
|
- sqlite.localhost
|
||||||
|
|
||||||
shaper_rules:
|
shaper_rules:
|
||||||
|
@ -145,14 +145,9 @@ unsupported_iq(Config) ->
|
|||||||
master_slave_cases(DB) ->
|
master_slave_cases(DB) ->
|
||||||
{offline_master_slave, [sequence],
|
{offline_master_slave, [sequence],
|
||||||
[master_slave_test(flex),
|
[master_slave_test(flex),
|
||||||
master_slave_test(send_all)] ++
|
master_slave_test(send_all),
|
||||||
case DB of
|
master_slave_test(from_mam),
|
||||||
riak -> [];
|
master_slave_test(mucsub_mam)]}.
|
||||||
_ -> [
|
|
||||||
master_slave_test(from_mam),
|
|
||||||
master_slave_test(mucsub_mam)]
|
|
||||||
end
|
|
||||||
}.
|
|
||||||
|
|
||||||
flex_master(Config) ->
|
flex_master(Config) ->
|
||||||
send_messages(Config, 5),
|
send_messages(Config, 5),
|
||||||
|
@ -172,9 +172,9 @@ setup_ejabberd_lib_path(Config) ->
|
|||||||
ok
|
ok
|
||||||
end.
|
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:
|
%% 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() ->
|
get_config_backends() ->
|
||||||
EnvBackends = case os:getenv("CT_BACKENDS") of
|
EnvBackends = case os:getenv("CT_BACKENDS") of
|
||||||
false -> ?BACKENDS;
|
false -> ?BACKENDS;
|
||||||
|
@ -96,11 +96,10 @@
|
|||||||
-define(SQLITE_VHOST, <<"sqlite.localhost">>).
|
-define(SQLITE_VHOST, <<"sqlite.localhost">>).
|
||||||
-define(LDAP_VHOST, <<"ldap.localhost">>).
|
-define(LDAP_VHOST, <<"ldap.localhost">>).
|
||||||
-define(EXTAUTH_VHOST, <<"extauth.localhost">>).
|
-define(EXTAUTH_VHOST, <<"extauth.localhost">>).
|
||||||
-define(RIAK_VHOST, <<"riak.localhost">>).
|
|
||||||
-define(S2S_VHOST, <<"s2s.localhost">>).
|
-define(S2S_VHOST, <<"s2s.localhost">>).
|
||||||
-define(UPLOAD_VHOST, <<"upload.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) ->
|
insert(Val, N, Tuple) ->
|
||||||
L = tuple_to_list(Tuple),
|
L = tuple_to_list(Tuple),
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
{sqlite, @sqlite@}.
|
{sqlite, @sqlite@}.
|
||||||
{pam, @pam@}.
|
{pam, @pam@}.
|
||||||
{zlib, @zlib@}.
|
{zlib, @zlib@}.
|
||||||
{riak, @riak@}.
|
|
||||||
{redis, @redis@}.
|
{redis, @redis@}.
|
||||||
{elixir, @elixir@}.
|
{elixir, @elixir@}.
|
||||||
{stun, @stun@}.
|
{stun, @stun@}.
|
||||||
|
Loading…
Reference in New Issue
Block a user