Rewrite mod_stats to use XML generator

This commit is contained in:
Evgeniy Khramtsov 2016-07-31 14:51:16 +03:00
parent e258462b6b
commit c0272ae766
4 changed files with 126 additions and 132 deletions

View File

@ -227,10 +227,14 @@
nick :: binary()}). nick :: binary()}).
-type muc_actor() :: #muc_actor{}. -type muc_actor() :: #muc_actor{}.
-record(stat_error, {code :: integer(),
reason = <<>> :: binary()}).
-type stat_error() :: #stat_error{}.
-record(stat, {name :: binary(), -record(stat, {name :: binary(),
units :: binary(), units = <<>> :: binary(),
value :: binary(), value = <<>> :: binary(),
error = [] :: [{integer(),'undefined' | binary()}]}). error :: #stat_error{}}).
-type stat() :: #stat{}. -type stat() :: #stat{}.
-record(addresses, {list = [] :: [#address{}]}). -record(addresses, {list = [] :: [#address{}]}).
@ -367,7 +371,8 @@
-record(stream_features, {sub_els = [] :: [any()]}). -record(stream_features, {sub_els = [] :: [any()]}).
-type stream_features() :: #stream_features{}. -type stream_features() :: #stream_features{}.
-record(stats, {stat = [] :: [#stat{}]}). -record(stats, {list = [] :: [#stat{}],
node = <<>> :: binary()}).
-type stats() :: #stats{}. -type stats() :: #stats{}.
-record(pubsub_items, {node :: binary(), -record(pubsub_items, {node :: binary(),
@ -980,6 +985,7 @@
feature_register() | feature_register() |
register() | register() |
sm_r() | sm_r() |
stat_error() |
error() | error() |
stream_error() | stream_error() |
muc_user() | muc_user() |

View File

@ -31,65 +31,39 @@
-behaviour(gen_mod). -behaviour(gen_mod).
-export([start/2, stop/1, process_local_iq/3, -export([start/2, stop/1, process_iq/1, mod_opt_type/1, depends/2]).
mod_opt_type/1, depends/2]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("logger.hrl"). -include("logger.hrl").
-include("jlib.hrl"). -include("xmpp.hrl").
start(Host, Opts) -> start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
one_queue), one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
?NS_STATS, ?MODULE, process_local_iq, IQDisc). ?MODULE, process_iq, IQDisc).
stop(Host) -> stop(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
?NS_STATS).
depends(_Host, _Opts) -> depends(_Host, _Opts) ->
[]. [].
process_local_iq(_From, To, process_iq(#iq{type = set, lang = Lang} = IQ) ->
#iq{id = _ID, type = Type, xmlns = XMLNS, Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
sub_el = SubEl, lang = Lang} = xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
IQ) -> process_iq(#iq{type = get, to = To, lang = Lang,
case Type of sub_els = [#stats{} = Stats]} = IQ) ->
set -> Node = str:tokens(Stats#stats.node, <<"/">>),
Txt = <<"Value 'set' of 'type' attribute is not allowed">>, Names = [Name || #stat{name = Name} <- Stats#stats.list],
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; case get_local_stats(To#jid.server, Node, Names, Lang) of
get -> {result, List} ->
#xmlel{children = Els} = SubEl, xmpp:make_iq_result(IQ, Stats#stats{list = List});
Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, SubEl), {error, Error} ->
<<"/">>), xmpp:make_error(IQ, Error)
Names = get_names(Els, []),
case get_local_stats(To#jid.server, Node, Names, Lang) of
{result, Res} ->
IQ#iq{type = result,
sub_el =
[#xmlel{name = <<"query">>,
attrs = [{<<"xmlns">>, XMLNS}],
children = Res}]};
{error, Error} ->
IQ#iq{type = error, sub_el = [SubEl, Error]}
end
end. end.
get_names([], Res) -> Res; -define(STAT(Name), #stat{name = Name}).
get_names([#xmlel{name = <<"stat">>, attrs = Attrs}
| Els],
Res) ->
Name = fxml:get_attr_s(<<"name">>, Attrs),
case Name of
<<"">> -> get_names(Els, Res);
_ -> get_names(Els, [Name | Res])
end;
get_names([_ | Els], Res) -> get_names(Els, Res).
-define(STAT(Name),
#xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}],
children = []}).
get_local_stats(_Server, [], [], _Lang) -> get_local_stats(_Server, [], [], _Lang) ->
{result, {result,
@ -115,7 +89,7 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
case search_running_node(ENode) of case search_running_node(ENode) of
false -> false ->
Txt = <<"No running node found">>, Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)}; {error, xmpp:err_item_not_found(Txt, Lang)};
Node -> Node ->
{result, {result,
lists:map(fun (Name) -> get_node_stat(Node, Name) end, lists:map(fun (Name) -> get_node_stat(Node, Name) end,
@ -123,27 +97,19 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
end; end;
get_local_stats(_Server, _, _, Lang) -> get_local_stats(_Server, _, _, Lang) ->
Txt = <<"No statistics found for this item">>, Txt = <<"No statistics found for this item">>,
{error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}. {error, xmpp:err_feature_not_implemented(Txt, Lang)}.
-define(STATVAL(Val, Unit), -define(STATVAL(Val, Unit), #stat{name = Name, units = Unit, value = Val}).
#xmlel{name = <<"stat">>,
attrs =
[{<<"name">>, Name}, {<<"units">>, Unit},
{<<"value">>, Val}],
children = []}).
-define(STATERR(Code, Desc), -define(STATERR(Code, Desc),
#xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}], #stat{name = Name,
children = error = #stat_error{code = Code, reason = Desc}}).
[#xmlel{name = <<"error">>,
attrs = [{<<"code">>, Code}],
children = [{xmlcdata, Desc}]}]}).
get_local_stat(Server, [], Name) get_local_stat(Server, [], Name)
when Name == <<"users/online">> -> when Name == <<"users/online">> ->
case catch ejabberd_sm:get_vh_session_list(Server) of case catch ejabberd_sm:get_vh_session_list(Server) of
{'EXIT', _Reason} -> {'EXIT', _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Users -> Users ->
?STATVAL((iolist_to_binary(integer_to_list(length(Users)))), ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))),
<<"users">>) <<"users">>)
@ -154,7 +120,7 @@ get_local_stat(Server, [], Name)
ejabberd_auth:get_vh_registered_users_number(Server) ejabberd_auth:get_vh_registered_users_number(Server)
of of
{'EXIT', _Reason} -> {'EXIT', _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
NUsers -> NUsers ->
?STATVAL((iolist_to_binary(integer_to_list(NUsers))), ?STATVAL((iolist_to_binary(integer_to_list(NUsers))),
<<"users">>) <<"users">>)
@ -163,7 +129,7 @@ get_local_stat(_Server, [], Name)
when Name == <<"users/all-hosts/online">> -> when Name == <<"users/all-hosts/online">> ->
case catch mnesia:table_info(session, size) of case catch mnesia:table_info(session, size) of
{'EXIT', _Reason} -> {'EXIT', _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Users -> Users ->
?STATVAL((iolist_to_binary(integer_to_list(Users))), ?STATVAL((iolist_to_binary(integer_to_list(Users))),
<<"users">>) <<"users">>)
@ -178,7 +144,7 @@ get_local_stat(_Server, [], Name)
?STATVAL((iolist_to_binary(integer_to_list(NumUsers))), ?STATVAL((iolist_to_binary(integer_to_list(NumUsers))),
<<"users">>); <<"users">>);
get_local_stat(_Server, _, Name) -> get_local_stat(_Server, _, Name) ->
?STATERR(<<"404">>, <<"Not Found">>). ?STATERR(404, <<"Not Found">>).
get_node_stat(Node, Name) get_node_stat(Node, Name)
when Name == <<"time/uptime">> -> when Name == <<"time/uptime">> ->
@ -186,7 +152,7 @@ get_node_stat(Node, Name)
[wall_clock]) [wall_clock])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
CPUTime -> CPUTime ->
?STATVAL(list_to_binary( ?STATVAL(list_to_binary(
io_lib:format("~.3f", io_lib:format("~.3f",
@ -198,7 +164,7 @@ get_node_stat(Node, Name)
case catch ejabberd_cluster:call(Node, erlang, statistics, [runtime]) case catch ejabberd_cluster:call(Node, erlang, statistics, [runtime])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
RunTime -> RunTime ->
?STATVAL(list_to_binary( ?STATVAL(list_to_binary(
io_lib:format("~.3f", io_lib:format("~.3f",
@ -211,7 +177,7 @@ get_node_stat(Node, Name)
dirty_get_my_sessions_list, []) dirty_get_my_sessions_list, [])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Users -> Users ->
?STATVAL((iolist_to_binary(integer_to_list(length(Users)))), ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))),
<<"users">>) <<"users">>)
@ -222,7 +188,7 @@ get_node_stat(Node, Name)
[transaction_commits]) [transaction_commits])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Transactions -> Transactions ->
?STATVAL((iolist_to_binary(integer_to_list(Transactions))), ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
<<"transactions">>) <<"transactions">>)
@ -233,7 +199,7 @@ get_node_stat(Node, Name)
[transaction_failures]) [transaction_failures])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Transactions -> Transactions ->
?STATVAL((iolist_to_binary(integer_to_list(Transactions))), ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
<<"transactions">>) <<"transactions">>)
@ -244,7 +210,7 @@ get_node_stat(Node, Name)
[transaction_restarts]) [transaction_restarts])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Transactions -> Transactions ->
?STATVAL((iolist_to_binary(integer_to_list(Transactions))), ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
<<"transactions">>) <<"transactions">>)
@ -255,13 +221,13 @@ get_node_stat(Node, Name)
[transaction_log_writes]) [transaction_log_writes])
of of
{badrpc, _Reason} -> {badrpc, _Reason} ->
?STATERR(<<"500">>, <<"Internal Server Error">>); ?STATERR(500, <<"Internal Server Error">>);
Transactions -> Transactions ->
?STATVAL((iolist_to_binary(integer_to_list(Transactions))), ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
<<"transactions">>) <<"transactions">>)
end; end;
get_node_stat(_, Name) -> get_node_stat(_, Name) ->
?STATERR(<<"404">>, <<"Not Found">>). ?STATERR(404, <<"Not Found">>).
search_running_node(SNode) -> search_running_node(SNode) ->
search_running_node(SNode, search_running_node(SNode,

View File

@ -2222,11 +2222,15 @@ encode({bookmark_url, _, _} = Url) ->
encode({bookmark_storage, _, _} = Storage) -> encode({bookmark_storage, _, _} = Storage) ->
encode_bookmarks_storage(Storage, encode_bookmarks_storage(Storage,
[{<<"xmlns">>, <<"storage:bookmarks">>}]); [{<<"xmlns">>, <<"storage:bookmarks">>}]);
encode({stat_error, _, _} = Error) ->
encode_stat_error(Error,
[{<<"xmlns">>,
<<"http://jabber.org/protocol/stats">>}]);
encode({stat, _, _, _, _} = Stat) -> encode({stat, _, _, _, _} = Stat) ->
encode_stat(Stat, encode_stat(Stat,
[{<<"xmlns">>, [{<<"xmlns">>,
<<"http://jabber.org/protocol/stats">>}]); <<"http://jabber.org/protocol/stats">>}]);
encode({stats, _} = Query) -> encode({stats, _, _} = Query) ->
encode_stats(Query, encode_stats(Query,
[{<<"xmlns">>, [{<<"xmlns">>,
<<"http://jabber.org/protocol/stats">>}]); <<"http://jabber.org/protocol/stats">>}]);
@ -2734,8 +2738,9 @@ get_name({bookmark_conference, _, _, _, _, _}) ->
<<"conference">>; <<"conference">>;
get_name({bookmark_url, _, _}) -> <<"url">>; get_name({bookmark_url, _, _}) -> <<"url">>;
get_name({bookmark_storage, _, _}) -> <<"storage">>; get_name({bookmark_storage, _, _}) -> <<"storage">>;
get_name({stat_error, _, _}) -> <<"error">>;
get_name({stat, _, _, _, _}) -> <<"stat">>; get_name({stat, _, _, _, _}) -> <<"stat">>;
get_name({stats, _}) -> <<"query">>; get_name({stats, _, _}) -> <<"query">>;
get_name({iq, _, _, _, _, _, _}) -> <<"iq">>; get_name({iq, _, _, _, _, _, _}) -> <<"iq">>;
get_name({message, _, _, _, _, _, _, _, _, _}) -> get_name({message, _, _, _, _, _, _, _, _, _}) ->
<<"message">>; <<"message">>;
@ -2939,9 +2944,11 @@ get_ns({bookmark_conference, _, _, _, _, _}) ->
get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>; get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>;
get_ns({bookmark_storage, _, _}) -> get_ns({bookmark_storage, _, _}) ->
<<"storage:bookmarks">>; <<"storage:bookmarks">>;
get_ns({stat_error, _, _}) ->
<<"http://jabber.org/protocol/stats">>;
get_ns({stat, _, _, _, _}) -> get_ns({stat, _, _, _, _}) ->
<<"http://jabber.org/protocol/stats">>; <<"http://jabber.org/protocol/stats">>;
get_ns({stats, _}) -> get_ns({stats, _, _}) ->
<<"http://jabber.org/protocol/stats">>; <<"http://jabber.org/protocol/stats">>;
get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>; get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>;
get_ns({message, _, _, _, _, _, _, _, _, _}) -> get_ns({message, _, _, _, _, _, _, _, _, _}) ->
@ -3254,8 +3261,9 @@ pp(bookmark_conference, 5) ->
[name, jid, autojoin, nick, password]; [name, jid, autojoin, nick, password];
pp(bookmark_url, 2) -> [name, url]; pp(bookmark_url, 2) -> [name, url];
pp(bookmark_storage, 2) -> [conference, url]; pp(bookmark_storage, 2) -> [conference, url];
pp(stat_error, 2) -> [code, reason];
pp(stat, 4) -> [name, units, value, error]; pp(stat, 4) -> [name, units, value, error];
pp(stats, 1) -> [stat]; pp(stats, 2) -> [list, node];
pp(iq, 6) -> [id, type, lang, from, to, sub_els]; pp(iq, 6) -> [id, type, lang, from, to, sub_els];
pp(message, 9) -> pp(message, 9) ->
[id, type, lang, from, to, subject, body, thread, [id, type, lang, from, to, subject, body, thread,
@ -25097,53 +25105,70 @@ encode_iq_attr_to(_val, _acc) ->
decode_stats(__TopXMLNS, __IgnoreEls, decode_stats(__TopXMLNS, __IgnoreEls,
{xmlel, <<"query">>, _attrs, _els}) -> {xmlel, <<"query">>, _attrs, _els}) ->
Stat = decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List = decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
[]), []),
{stats, Stat}. Node = decode_stats_attrs(__TopXMLNS, _attrs,
undefined),
{stats, List, Node}.
decode_stats_els(__TopXMLNS, __IgnoreEls, [], Stat) -> decode_stats_els(__TopXMLNS, __IgnoreEls, [], List) ->
lists:reverse(Stat); lists:reverse(List);
decode_stats_els(__TopXMLNS, __IgnoreEls, decode_stats_els(__TopXMLNS, __IgnoreEls,
[{xmlel, <<"stat">>, _attrs, _} = _el | _els], Stat) -> [{xmlel, <<"stat">>, _attrs, _} = _el | _els], List) ->
case get_attr(<<"xmlns">>, _attrs) of case get_attr(<<"xmlns">>, _attrs) of
<<"">> <<"">>
when __TopXMLNS == when __TopXMLNS ==
<<"http://jabber.org/protocol/stats">> -> <<"http://jabber.org/protocol/stats">> ->
decode_stats_els(__TopXMLNS, __IgnoreEls, _els, decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
[decode_stat(__TopXMLNS, __IgnoreEls, _el) | Stat]); [decode_stat(__TopXMLNS, __IgnoreEls, _el) | List]);
<<"http://jabber.org/protocol/stats">> -> <<"http://jabber.org/protocol/stats">> ->
decode_stats_els(__TopXMLNS, __IgnoreEls, _els, decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
[decode_stat(<<"http://jabber.org/protocol/stats">>, [decode_stat(<<"http://jabber.org/protocol/stats">>,
__IgnoreEls, _el) __IgnoreEls, _el)
| Stat]); | List]);
_ -> _ ->
decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat) decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List)
end; end;
decode_stats_els(__TopXMLNS, __IgnoreEls, [_ | _els], decode_stats_els(__TopXMLNS, __IgnoreEls, [_ | _els],
Stat) -> List) ->
decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat). decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List).
encode_stats({stats, Stat}, _xmlns_attrs) -> decode_stats_attrs(__TopXMLNS,
_els = lists:reverse('encode_stats_$stat'(Stat, [])), [{<<"node">>, _val} | _attrs], _Node) ->
_attrs = _xmlns_attrs, decode_stats_attrs(__TopXMLNS, _attrs, _val);
decode_stats_attrs(__TopXMLNS, [_ | _attrs], Node) ->
decode_stats_attrs(__TopXMLNS, _attrs, Node);
decode_stats_attrs(__TopXMLNS, [], Node) ->
decode_stats_attr_node(__TopXMLNS, Node).
encode_stats({stats, List, Node}, _xmlns_attrs) ->
_els = lists:reverse('encode_stats_$list'(List, [])),
_attrs = encode_stats_attr_node(Node, _xmlns_attrs),
{xmlel, <<"query">>, _attrs, _els}. {xmlel, <<"query">>, _attrs, _els}.
'encode_stats_$stat'([], _acc) -> _acc; 'encode_stats_$list'([], _acc) -> _acc;
'encode_stats_$stat'([Stat | _els], _acc) -> 'encode_stats_$list'([List | _els], _acc) ->
'encode_stats_$stat'(_els, 'encode_stats_$list'(_els,
[encode_stat(Stat, []) | _acc]). [encode_stat(List, []) | _acc]).
decode_stats_attr_node(__TopXMLNS, undefined) -> <<>>;
decode_stats_attr_node(__TopXMLNS, _val) -> _val.
encode_stats_attr_node(<<>>, _acc) -> _acc;
encode_stats_attr_node(_val, _acc) ->
[{<<"node">>, _val} | _acc].
decode_stat(__TopXMLNS, __IgnoreEls, decode_stat(__TopXMLNS, __IgnoreEls,
{xmlel, <<"stat">>, _attrs, _els}) -> {xmlel, <<"stat">>, _attrs, _els}) ->
Error = decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error = decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
[]), undefined),
{Name, Units, Value} = decode_stat_attrs(__TopXMLNS, {Name, Units, Value} = decode_stat_attrs(__TopXMLNS,
_attrs, undefined, undefined, _attrs, undefined, undefined,
undefined), undefined),
{stat, Name, Units, Value, Error}. {stat, Name, Units, Value, Error}.
decode_stat_els(__TopXMLNS, __IgnoreEls, [], Error) -> decode_stat_els(__TopXMLNS, __IgnoreEls, [], Error) ->
lists:reverse(Error); Error;
decode_stat_els(__TopXMLNS, __IgnoreEls, decode_stat_els(__TopXMLNS, __IgnoreEls,
[{xmlel, <<"error">>, _attrs, _} = _el | _els], [{xmlel, <<"error">>, _attrs, _} = _el | _els],
Error) -> Error) ->
@ -25152,13 +25177,11 @@ decode_stat_els(__TopXMLNS, __IgnoreEls,
when __TopXMLNS == when __TopXMLNS ==
<<"http://jabber.org/protocol/stats">> -> <<"http://jabber.org/protocol/stats">> ->
decode_stat_els(__TopXMLNS, __IgnoreEls, _els, decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
[decode_stat_error(__TopXMLNS, __IgnoreEls, _el) decode_stat_error(__TopXMLNS, __IgnoreEls, _el));
| Error]);
<<"http://jabber.org/protocol/stats">> -> <<"http://jabber.org/protocol/stats">> ->
decode_stat_els(__TopXMLNS, __IgnoreEls, _els, decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
[decode_stat_error(<<"http://jabber.org/protocol/stats">>, decode_stat_error(<<"http://jabber.org/protocol/stats">>,
__IgnoreEls, _el) __IgnoreEls, _el));
| Error]);
_ -> _ ->
decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error) decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error)
end; end;
@ -25196,10 +25219,9 @@ encode_stat({stat, Name, Units, Value, Error},
_xmlns_attrs))), _xmlns_attrs))),
{xmlel, <<"stat">>, _attrs, _els}. {xmlel, <<"stat">>, _attrs, _els}.
'encode_stat_$error'([], _acc) -> _acc; 'encode_stat_$error'(undefined, _acc) -> _acc;
'encode_stat_$error'([Error | _els], _acc) -> 'encode_stat_$error'(Error, _acc) ->
'encode_stat_$error'(_els, [encode_stat_error(Error, []) | _acc].
[encode_stat_error(Error, []) | _acc]).
decode_stat_attr_name(__TopXMLNS, undefined) -> decode_stat_attr_name(__TopXMLNS, undefined) ->
erlang:error({xmpp_codec, erlang:error({xmpp_codec,
@ -25209,41 +25231,39 @@ decode_stat_attr_name(__TopXMLNS, _val) -> _val.
encode_stat_attr_name(_val, _acc) -> encode_stat_attr_name(_val, _acc) ->
[{<<"name">>, _val} | _acc]. [{<<"name">>, _val} | _acc].
decode_stat_attr_units(__TopXMLNS, undefined) -> decode_stat_attr_units(__TopXMLNS, undefined) -> <<>>;
undefined;
decode_stat_attr_units(__TopXMLNS, _val) -> _val. decode_stat_attr_units(__TopXMLNS, _val) -> _val.
encode_stat_attr_units(undefined, _acc) -> _acc; encode_stat_attr_units(<<>>, _acc) -> _acc;
encode_stat_attr_units(_val, _acc) -> encode_stat_attr_units(_val, _acc) ->
[{<<"units">>, _val} | _acc]. [{<<"units">>, _val} | _acc].
decode_stat_attr_value(__TopXMLNS, undefined) -> decode_stat_attr_value(__TopXMLNS, undefined) -> <<>>;
undefined;
decode_stat_attr_value(__TopXMLNS, _val) -> _val. decode_stat_attr_value(__TopXMLNS, _val) -> _val.
encode_stat_attr_value(undefined, _acc) -> _acc; encode_stat_attr_value(<<>>, _acc) -> _acc;
encode_stat_attr_value(_val, _acc) -> encode_stat_attr_value(_val, _acc) ->
[{<<"value">>, _val} | _acc]. [{<<"value">>, _val} | _acc].
decode_stat_error(__TopXMLNS, __IgnoreEls, decode_stat_error(__TopXMLNS, __IgnoreEls,
{xmlel, <<"error">>, _attrs, _els}) -> {xmlel, <<"error">>, _attrs, _els}) ->
Cdata = decode_stat_error_els(__TopXMLNS, __IgnoreEls, Reason = decode_stat_error_els(__TopXMLNS, __IgnoreEls,
_els, <<>>), _els, <<>>),
Code = decode_stat_error_attrs(__TopXMLNS, _attrs, Code = decode_stat_error_attrs(__TopXMLNS, _attrs,
undefined), undefined),
{Code, Cdata}. {stat_error, Code, Reason}.
decode_stat_error_els(__TopXMLNS, __IgnoreEls, [], decode_stat_error_els(__TopXMLNS, __IgnoreEls, [],
Cdata) -> Reason) ->
decode_stat_error_cdata(__TopXMLNS, Cdata); decode_stat_error_cdata(__TopXMLNS, Reason);
decode_stat_error_els(__TopXMLNS, __IgnoreEls, decode_stat_error_els(__TopXMLNS, __IgnoreEls,
[{xmlcdata, _data} | _els], Cdata) -> [{xmlcdata, _data} | _els], Reason) ->
decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els, decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els,
<<Cdata/binary, _data/binary>>); <<Reason/binary, _data/binary>>);
decode_stat_error_els(__TopXMLNS, __IgnoreEls, decode_stat_error_els(__TopXMLNS, __IgnoreEls,
[_ | _els], Cdata) -> [_ | _els], Reason) ->
decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els, decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els,
Cdata). Reason).
decode_stat_error_attrs(__TopXMLNS, decode_stat_error_attrs(__TopXMLNS,
[{<<"code">>, _val} | _attrs], _Code) -> [{<<"code">>, _val} | _attrs], _Code) ->
@ -25254,8 +25274,9 @@ decode_stat_error_attrs(__TopXMLNS, [_ | _attrs],
decode_stat_error_attrs(__TopXMLNS, [], Code) -> decode_stat_error_attrs(__TopXMLNS, [], Code) ->
decode_stat_error_attr_code(__TopXMLNS, Code). decode_stat_error_attr_code(__TopXMLNS, Code).
encode_stat_error({Code, Cdata}, _xmlns_attrs) -> encode_stat_error({stat_error, Code, Reason},
_els = encode_stat_error_cdata(Cdata, []), _xmlns_attrs) ->
_els = encode_stat_error_cdata(Reason, []),
_attrs = encode_stat_error_attr_code(Code, _attrs = encode_stat_error_attr_code(Code,
_xmlns_attrs), _xmlns_attrs),
{xmlel, <<"error">>, _attrs, _els}. {xmlel, <<"error">>, _attrs, _els}.
@ -25274,10 +25295,10 @@ decode_stat_error_attr_code(__TopXMLNS, _val) ->
encode_stat_error_attr_code(_val, _acc) -> encode_stat_error_attr_code(_val, _acc) ->
[{<<"code">>, enc_int(_val)} | _acc]. [{<<"code">>, enc_int(_val)} | _acc].
decode_stat_error_cdata(__TopXMLNS, <<>>) -> undefined; decode_stat_error_cdata(__TopXMLNS, <<>>) -> <<>>;
decode_stat_error_cdata(__TopXMLNS, _val) -> _val. decode_stat_error_cdata(__TopXMLNS, _val) -> _val.
encode_stat_error_cdata(undefined, _acc) -> _acc; encode_stat_error_cdata(<<>>, _acc) -> _acc;
encode_stat_error_cdata(_val, _acc) -> encode_stat_error_cdata(_val, _acc) ->
[{xmlcdata, _val} | _acc]. [{xmlcdata, _val} | _acc].

View File

@ -289,7 +289,8 @@
-xml(stat_error, -xml(stat_error,
#elem{name = <<"error">>, #elem{name = <<"error">>,
xmlns = <<"http://jabber.org/protocol/stats">>, xmlns = <<"http://jabber.org/protocol/stats">>,
result = {'$code', '$cdata'}, result = {stat_error, '$code', '$reason'},
cdata = #cdata{default = <<"">>, label = '$reason'},
attrs = [#attr{name = <<"code">>, attrs = [#attr{name = <<"code">>,
required = true, required = true,
enc = {enc_int, []}, enc = {enc_int, []},
@ -301,17 +302,17 @@
result = {stat, '$name', '$units', '$value', '$error'}, result = {stat, '$name', '$units', '$value', '$error'},
attrs = [#attr{name = <<"name">>, attrs = [#attr{name = <<"name">>,
required = true}, required = true},
#attr{name = <<"units">>}, #attr{name = <<"units">>, default = <<"">>},
#attr{name = <<"value">>}], #attr{name = <<"value">>, default = <<"">>}],
refs = [#ref{name = stat_error, refs = [#ref{name = stat_error, label = '$error',
label = '$error'}]}). min = 0, max = 1}]}).
-xml(stats, -xml(stats,
#elem{name = <<"query">>, #elem{name = <<"query">>,
xmlns = <<"http://jabber.org/protocol/stats">>, xmlns = <<"http://jabber.org/protocol/stats">>,
result = {stats, '$stat'}, result = {stats, '$list', '$node'},
refs = [#ref{name = stat, attrs = [#attr{name = <<"node">>, default = <<"">>}],
label = '$stat'}]}). refs = [#ref{name = stat, label = '$list'}]}).
-xml(iq, -xml(iq,
#elem{name = <<"iq">>, #elem{name = <<"iq">>,