diff --git a/config/prd/sys.config b/config/prd/sys.config index 98eacdc..57c7b51 100644 --- a/config/prd/sys.config +++ b/config/prd/sys.config @@ -48,29 +48,6 @@ {erlbin_number, 15} ]}, - {lager, - [ - {log_root, "log"}, - %% Default handlers for lager/lager_event - {handlers, - [ - {lager_console_backend, debug} - ]}, - - %% Any other sinks - {extra_sinks, - [ - {audit_lager_event, - [{handlers, - [ - {lager_console_backend, debug} - ] - }, - {async_threshold, 500}, - {async_threshold_window, 50}] - }] - } - ]}, {kernel, [{ logger, diff --git a/epo b/epo deleted file mode 100755 index c4adcf2..0000000 Binary files a/epo and /dev/null differ diff --git a/key.priv b/key.priv deleted file mode 100644 index 8e1b30d..0000000 --- a/key.priv +++ /dev/null @@ -1,7 +0,0 @@ -Crossbar.io node private key - KEEP THIS SAFE! - -creator: frepond@shiryu.local -created-at: 2018-09-03T16:44:33.273Z -machine-id: C02PD24MG3QD -public-key-ed25519: fb1add1e0e941f5a3f499228097834d528c55f3079c26ca49edcb68b5b51147a -private-key-ed25519: 8106ad3e9ad50a548853303705cca921741c86478b39186584bfaafacaa49a53 diff --git a/key.pub b/key.pub deleted file mode 100644 index a5e46d6..0000000 --- a/key.pub +++ /dev/null @@ -1,6 +0,0 @@ -Crossbar.io node public key - -creator: frepond@shiryu.local -created-at: 2018-09-03T16:44:33.273Z -machine-id: C02PD24MG3QD -public-key-ed25519: fb1add1e0e941f5a3f499228097834d528c55f3079c26ca49edcb68b5b51147a diff --git a/priv/lang/wamp_service.en.mo b/priv/lang/wamp_service.en.mo deleted file mode 100644 index cf895fd..0000000 Binary files a/priv/lang/wamp_service.en.mo and /dev/null differ diff --git a/priv/lang/wamp_service.en.po b/priv/lang/wamp_service.en.po deleted file mode 100644 index d8759f3..0000000 --- a/priv/lang/wamp_service.en.po +++ /dev/null @@ -1,37 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: wamp_service\n" -"POT-Creation-Date: 2017-09-20 18:16--300\n" -"PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: en\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.3\n" - -msgid "Resource not found." -msgstr "Resource not found." - -msgid "Service timeout." -msgstr "Service timeout." - -msgid "The resource you are trying to retrieve does not exist." -msgstr "The resource you are trying to retrieve does not exist." - -msgid "The user does not have the required permissions to access the resource." -msgstr "The user does not have the required permissions to access the resource." - -msgid "There was a timeout resolving the operation." -msgstr "There was a timeout resolving the operation." - -msgid "There was an internal error, please contact the administrator." -msgstr "There was an internal error, please contact the administrator." - -msgid "Unauthorized user." -msgstr "Unauthorized user." - -msgid "Internal error." -msgstr "Internal error." diff --git a/priv/lang/wamp_service.es_AR.mo b/priv/lang/wamp_service.es_AR.mo deleted file mode 100644 index d2e0966..0000000 Binary files a/priv/lang/wamp_service.es_AR.mo and /dev/null differ diff --git a/priv/lang/wamp_service.es_AR.po b/priv/lang/wamp_service.es_AR.po deleted file mode 100644 index e40c18c..0000000 --- a/priv/lang/wamp_service.es_AR.po +++ /dev/null @@ -1,37 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: wamp_service\n" -"POT-Creation-Date: 2017-09-20 18:16--300\n" -"PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: es_AR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.3\n" - -msgid "Resource not found." -msgstr "No se encontró el recurso." - -msgid "Service timeout." -msgstr "El servicio tardó demasiado." - -msgid "The resource you are trying to retrieve does not exist." -msgstr "No existe el recurso que está intentando recuperar." - -msgid "The user does not have the required permissions to access the resource." -msgstr "El usuario no tiene los permisos necesarios para acceder al recurso." - -msgid "There was a timeout resolving the operation." -msgstr "Se excedió el tiempo de espera de la operación." - -msgid "There was an internal error, please contact the administrator." -msgstr "Hubo un error interno, póngase en contacto con el administrador." - -msgid "Unauthorized user." -msgstr "Usuario no autorizado." - -msgid "Internal error." -msgstr "Error interno." diff --git a/priv/lang/wamp_service.pot b/priv/lang/wamp_service.pot deleted file mode 100644 index 3b120a0..0000000 --- a/priv/lang/wamp_service.pot +++ /dev/null @@ -1,31 +0,0 @@ - -msgid "" -msgstr "" -"Project-Id-Version: wamp_service\n" -"POT-Creation-Date: 2018-05-23 12:43--300\n" -"Plural-Forms: nplurals=1; plural=1;\n" - -msgid "Internal error." -msgstr "" - -msgid "Resource not found." -msgstr "" - -msgid "Service timeout." -msgstr "" - -msgid "The resource you are trying to retrieve does not exist." -msgstr "" - -msgid "The user does not have the required permissions to access the resource" -"." -msgstr "" - -msgid "There was a timeout resolving the operation." -msgstr "" - -msgid "There was an internal error, please contact the administrator." -msgstr "" - -msgid "Unauthorized user." -msgstr "" diff --git a/rebar.config b/rebar.config index d1dc039..b45d579 100644 --- a/rebar.config +++ b/rebar.config @@ -1,32 +1,30 @@ -{erl_opts, - [debug_info, - {parse_transform, lager_transform}, - {parse_transform, epo_gettext}, - {gettext, wamp_service_compiled_po} +{minimum_otp_vsn, "23.0"}. + +{erl_opts,[ + debug_info ]}. {deps, - [{wamper, {git, "https://github.com/frepond/wamper.git", {branch, "master"}}}, + [ msgpack, - {pbkdf2, {git, "https://github.com/pma/erlang-pbkdf2", {branch, "master"}}}, - {jsx, {git, "https://github.com/talentdeficit/jsx.git", {tag, "2.8.2"}}}, - {awre, {git, "https://github.com/frepond/awre.git", {branch, "master"}}}, - {lager , {git, "https://github.com/erlang-lager/lager.git", {tag, "3.6.4"}}}, - {epo_runtime, {git, "https://github.com/brigadier/epo_runtime.git", {branch, "master"}}}, - {backoff, {git, "https://github.com/ferd/backoff.git", {branch, master}}} + {pbkdf2, + {git, "https://github.com/leapsight-oss/erlang-pbkdf2.git", {branch, "master"}} + }, + jsone, + {awre, {git, "https://github.com/leapsight/awre.git", {branch, "master"}}}, + {wamper, {git, "https://github.com/leapsight/wamper.git", {branch, "master"}}}, + backoff ]}. {relx, - [{release, {wamp_service, "0.5.0" }, + [{release, {wamp_service, "0.6.0" }, [kernel, stdlib, sasl, %% -------------- - lager, - jsx, + jsone, msgpack, pbkdf2, - epo_runtime, wamper, awre, backoff, @@ -84,7 +82,8 @@ ]}, {test, [{deps, [meck]}, - {erl_opts, [debug_info, export_all]} + {erl_opts, [debug_info, export_all]}, + {sys_config, "./config/dev/sys.config"} ]} ]}. @@ -92,10 +91,10 @@ {plugins, [rebar3_auto]}. -{shell, [{config, "config/dev/sys.config"}, {apps, [sasl, lager, msgpack, pbkdf2, jsx, wamper, awre, wamp_service]}]}. +{shell, [{config, "config/dev/sys.config"}, {apps, [sasl, msgpack, pbkdf2, jsone, wamper, awre, wamp_service]}]}. {elvis, - [#{dirs => ["apps/accounts/src"], + [#{dirs => ["src"], filter => "*.erl", rules => [ %% {elvis_style, line_length, @@ -141,7 +140,7 @@ }, #{dirs => ["."], filter => "rebar.config", - rules => [{elvis_project, no_deps_master_rebar, #{ignore => [awre, wamper, pbkdf2, epo_runtime]}}, + rules => [{elvis_project, no_deps_master_rebar, #{ignore => [awre, wamper, pbkdf2]}}, {elvis_project, protocol_for_deps_rebar, #{ignore => []}}] } ] diff --git a/rebar.lock b/rebar.lock index ebb9990..a3de770 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,36 +1,26 @@ -{"1.1.0", +{"1.2.0", [{<<"awre">>, - {git,"https://github.com/frepond/awre.git", - {ref,"7ca1a27a4250e0a3caff2288f02195810b164c0c"}}, + {git,"https://github.com/leapsight/awre.git", + {ref,"3b39c445e73f2067eb345328d80f6b6aec9d6540"}}, 0}, - {<<"backoff">>, - {git,"https://github.com/ferd/backoff.git", - {ref,"dfb19a20c37b73af067edc3c335624bdf9517396"}}, - 0}, - {<<"epo_runtime">>, - {git,"https://github.com/brigadier/epo_runtime.git", - {ref,"c403f40237abc93fedfbbed6462f77121bf14be9"}}, - 0}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1}, - {<<"jsx">>, - {git,"https://github.com/talentdeficit/jsx.git", - {ref,"d4b6d3dc5fd9e759ff7a0c476654ea5124f5bae9"}}, - 0}, - {<<"lager">>, - {git,"https://github.com/erlang-lager/lager.git", - {ref,"bf60290101306b3cc26544d0d181a5cff8931e82"}}, - 0}, - {<<"msgpack">>,{pkg,<<"msgpack">>,<<"0.7.0">>},0}, + {<<"backoff">>,{pkg,<<"backoff">>,<<"1.1.6">>},0}, + {<<"jsone">>,{pkg,<<"jsone">>,<<"1.8.1">>},0}, + {<<"msgpack">>,{pkg,<<"msgpack">>,<<"0.8.1">>},0}, {<<"pbkdf2">>, - {git,"https://github.com/pma/erlang-pbkdf2", - {ref,"93b290d72b107747c717fb1f55811d2ebc1b73ed"}}, + {git,"https://github.com/leapsight-oss/erlang-pbkdf2.git", + {ref,"84f964b1875b047c3ad93d43cc350c45d6e27f9c"}}, 0}, {<<"wamper">>, - {git,"https://github.com/frepond/wamper.git", - {ref,"b5aa4ac167f5d2fca1af1a0de45a6698711c5903"}}, + {git,"https://github.com/leapsight/wamper.git", + {ref,"0d7cc7c2ebd396f0cf1e8d512c708f4d855157d0"}}, 0}]}. [ {pkg_hash,[ - {<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>}, - {<<"msgpack">>, <<"128AE0A2227C7E7A2847C0F0F73551C268464F8C1EE96BFFB920BC0A5712B295">>}]} + {<<"backoff">>, <<"83B72ED2108BA1EE8F7D1C22E0B4A00CFE3593A67DBC792799E8CCE9F42F796B">>}, + {<<"jsone">>, <<"6BC74D3863D55D420077346DA97C601711017A057F2FD1DF65D6D65DD562FBAB">>}, + {<<"msgpack">>, <<"DEB35C13291EAFE56AD9870374C2EAA92323DC5503D50432EBCAF47052E6D343">>}]}, +{pkg_hash_ext,[ + {<<"backoff">>, <<"CF0CFFF8995FB20562F822E5CC47D8CCF664C5ECDC26A684CBE85C225F9D7C39">>}, + {<<"jsone">>, <<"C78918124148C51A7A84C678E39BBC6281F8CB582F1D88584628A98468E99738">>}, + {<<"msgpack">>, <<"04D9A75BC6F4BED8627EE1E7AA9DF37601F510FDC786A84FE932BB21D765565F">>}]} ]. diff --git a/src/example/wamp_service_example.erl b/src/example/wamp_service_example.erl index f081963..134e1dc 100644 --- a/src/example/wamp_service_example.erl +++ b/src/example/wamp_service_example.erl @@ -1,6 +1,8 @@ %% Demo service -module(wamp_service_example). +-include_lib("kernel/include/logger.hrl"). + -export([add/3]). -export([echo/2]). -export([multiple_results/1]). @@ -17,14 +19,14 @@ -spec add(number(), number(), map()) -> number(). add(A, B, _Opts) -> - ok = lager:debug("add called, sent ~p + ~p.", [A, B]), + ok = ?LOG_DEBUG("add called, sent ~p + ~p.", [A, B]), A + B. -spec echo(any(), map()) -> any(). echo(Msg, _Opts) -> - ok = lager:debug("echo called..."), + ok = ?LOG_DEBUG("echo called..."), timer:sleep(2500), - ok = lager:debug("echo sent ~p.", [Msg]), + ok = ?LOG_DEBUG("echo sent ~p.", [Msg]), Msg. -spec multiple_results(map()) -> list(). @@ -73,9 +75,9 @@ timeout(_Opts) -> -spec onhello(any(), map()) -> ok. onhello(Msg, _Opts) -> - ok = lager:debug("event from com.example.onhello ~p.", [Msg]), + ok = ?LOG_DEBUG("event from com.example.onhello ~p.", [Msg]), ok. onadd(A, B, _Opts) -> - ok = lager:debug("event from com.example.onadd ~p.", [A + B]), + ok = ?LOG_DEBUG("event from com.example.onadd ~p.", [A + B]), ok. diff --git a/src/wamp_service.app.src b/src/wamp_service.app.src index 9d84a4d..ee80bdf 100644 --- a/src/wamp_service.app.src +++ b/src/wamp_service.app.src @@ -7,8 +7,7 @@ [kernel, stdlib, sasl, - lager, - jsx, + jsone, msgpack, pbkdf2, wamper, diff --git a/src/wamp_service.erl b/src/wamp_service.erl index 537475e..88e4465 100644 --- a/src/wamp_service.erl +++ b/src/wamp_service.erl @@ -4,6 +4,8 @@ -module(wamp_service). +-include_lib("kernel/include/logger.hrl"). + -define(DELTA, 100). -export([call/3, call/4, maybe_error/1, publish/3, register/3, register/4, unregister/1, status/0]). @@ -22,17 +24,20 @@ call(Uri, Args, ArgsKw, Timeout) try WampRes = gen_server:call(wamp_caller, {call, Uri, Args, ArgsKw, Timeout}, Timeout + 100), case WampRes of - {ok, _, [Res], _} -> - _ = lager:debug("call uri=~p result=~p", [Uri, Res]), - {ok, Res}; - {ok, _, [], _} -> - _ = lager:debug("call uri=~p result=~p", [Uri, undefined]), + {ok, _, undefined, _RKWArgs} -> + _ = ?LOG_DEBUG("call uri=~p result=~p", [Uri, undefined]), + {ok, undefined}; + {ok, _, [], _RKWArgs} -> + _ = ?LOG_DEBUG("call uri=~p result=~p", [Uri, undefined]), {ok, undefined}; - {ok, _, Res = [_, _ | _], _} -> - _ = lager:debug("call uri=~p result=~p", [Uri, Res]), - {ok, Res}; + {ok, _, [Arg], _RKWArgs} -> + _ = ?LOG_DEBUG("call uri=~p result=~p", [Uri, Arg]), + {ok, Arg}; + {ok, _, RArgs, _RKWArgs} -> + _ = ?LOG_DEBUG("call uri=~p result=~p", [Uri, RArgs]), + {ok, RArgs}; {error, _, Key, _, Map} -> - _ = lager:debug("call uri=~p key=~p error=~p", [Uri, Key, Map]), + _ = ?LOG_DEBUG("call uri=~p key=~p error=~p", [Uri, Key, Map]), {error, Key, Map} end catch diff --git a/src/wamp_service_compiled_po.erl b/src/wamp_service_compiled_po.erl deleted file mode 100644 index 3ec7f7a..0000000 --- a/src/wamp_service_compiled_po.erl +++ /dev/null @@ -1,82 +0,0 @@ -%%EPO COMPILED FILE -%% -*- coding: utf-8 -*- --module('wamp_service_compiled_po'). --compile(nowarn_unused_vars). --compile(nowarn_unused_function). --compile(nowarn_unused_record). - --record(porec2, {msgstr, msgstr_n = {}, n_max}). --export([get_record/2, get_idx/2]). --ignore_xref([get_record/2, get_idx/2]). -get_idx(N, <<"es_AR">>) -> - to_integer(to_integer(N) - =/= to_integer(1)); -get_idx(N, <<"en">>) -> - to_integer(to_integer(N) - =/= to_integer(1)); -get_idx(N, <>) -> - get_idx(N, Locale2); -get_idx(_, _) -> - 0. - -get_record(Key, Locale) -> - case Key of <<"Unauthorized user."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"Usuario no autorizado."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"Unauthorized user."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"The user does not have the required permissions to access the resource."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"El usuario no tiene los permisos necesarios para acceder al recurso."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"The user does not have the required permissions to access the resource."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"Resource not found."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"No se encontró el recurso."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"Resource not found."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"There was an unknown error, please contact the administrator."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"Hubo un error desconocido, póngase en contacto con el administrador."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"There was an unknown error, please contact the administrator."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"The resource you are trying to retrieve does not exist."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"No existe el recurso que está intentando recuperar."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"The resource you are trying to retrieve does not exist."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"Unknown error."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"Error desconocido."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"Unknown error."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"Service timeout."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"El servicio tardó demasiado."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"Service timeout."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - <<"There was a timeout resolving the operation."/utf8>> -> - case Locale of - <<"es_AR">> -> #porec2{msgstr = <<"Se excedió el tiempo de espera de la operación."/utf8>>, msgstr_n = {}, n_max = 0}; - <<"en">> -> #porec2{msgstr = <<"There was a timeout resolving the operation."/utf8>>, msgstr_n = {}, n_max = 0}; - _ -> undefined - end; - _ -> undefined - end. - -to_integer(true) -> to_integer(1); -to_integer(false) -> to_integer(0); -to_integer(N) when is_integer(N) -> N. - -to_boolean(true) -> true; -to_boolean(false) -> false; -to_boolean(N) when N > 0 -> to_boolean(true); -to_boolean(N) when N == 0 -> to_boolean(false). - \ No newline at end of file diff --git a/src/wamp_service_dispatcher.erl b/src/wamp_service_dispatcher.erl index b4bec7e..51eba84 100644 --- a/src/wamp_service_dispatcher.erl +++ b/src/wamp_service_dispatcher.erl @@ -5,6 +5,9 @@ -behaviour(gen_server). +-include_lib("kernel/include/logger.hrl"). + + -export([start_link/1]). %% gen_server callbacks @@ -29,15 +32,18 @@ start_link(Opts) -> %%-------------------------------------------------------------------- init(Opts) -> process_flag(trap_exit, true), + Host = proplists:get_value(hostname, Opts), Port = proplists:get_value(port, Opts), Realm = proplists:get_value(realm, Opts), Encoding = proplists:get_value(encoding, Opts), CbConf = normalize_cb_conf(proplists:get_value(callbacks, Opts, #{})), - Retries = proplists:get_value(retries, Opts, 10), - InitBackoff = proplists:get_value(backoff, Opts, 500), - Backoff = backoff:init(InitBackoff, 120000), - Reconnect = proplists:get_value(reconnect, Opts, false), + + %% reconnect options + Reconnect = wamp_service_utils:reconnect(Opts), + Retries = wamp_service_utils:reconnect_retries(Opts), + Backoff = wamp_service_utils:init_backoff(Reconnect, Opts), + State = #{host => Host, port => Port, realm => Realm, encoding => Encoding, retries => Retries, backoff => Backoff, reconnect => Reconnect, cb_conf => CbConf, callbacks => #{}, @@ -133,20 +139,25 @@ handle_invocation({invocation, RequestId, RegistrationId, Details, Args, ArgsKw} #{conn := Conn, callbacks := Callbacks}) -> #{RegistrationId := #{handler := Handler, scopes := Scopes}} = Callbacks, try - _ = lager:debug("handle invocation request_id=~p registration_id=~p handler=~p args=~p args_kw=~p, scope=~p", + _ = ?LOG_DEBUG("handle invocation request_id=~p registration_id=~p handler=~p args=~p args_kw=~p, scope=~p", [RequestId, RegistrationId, Handler, Args, ArgsKw, Scopes]), handle_security(ArgsKw, Scopes), set_locale(ArgsKw), Res = exec_callback(Handler, wamp_service_utils:args(Args) ++ [wamp_service_utils:options(ArgsKw)]), handle_result(Conn, RequestId, Details, Res, ArgsKw) catch - throw:not_found -> % do not log not found errors - handle_invocation_error(Conn, RequestId, Handler, throw, not_found); - Class:Reason -> + throw:not_found:Stacktrace -> % do not log not found errors + handle_invocation_error( + Conn, RequestId, Handler, throw, not_found, Stacktrace); + Class:Reason:Stacktrace -> Args1 = obfuscate_pass(Args), - lager:error("handle invocation class=~p reason=~p call handler=~p args=~p args_kw=~p stacktrace=~p", - [Class, Reason, Handler, Args1, ArgsKw, erlang:get_stacktrace()]), - handle_invocation_error(Conn, RequestId, Handler, Class, Reason) + _ = ?LOG_ERROR( + "handle invocation class=~p reason=~p call handler=~p args=~p args_kw=~p stacktrace=~p", + [Class, Reason, Handler, Args1, ArgsKw, Stacktrace] + ), + handle_invocation_error( + Conn, RequestId, Handler, Class, Reason, Stacktrace + ) end. %% @private @@ -154,14 +165,14 @@ handle_event({event, SubscriptionId, PublicationId, _Details, Args, ArgsKw}, #{callbacks := Callbacks}) -> #{SubscriptionId := #{handler := Handler}} = Callbacks, try - _ = lager:debug("handle event subscription_id=~p publication_id=~p handler=~p args=~p args_kw=~p", + _ = ?LOG_DEBUG("handle event subscription_id=~p publication_id=~p handler=~p args=~p args_kw=~p", [SubscriptionId, PublicationId, Handler, Args, ArgsKw]), exec_callback(Handler, wamp_service_utils:args(Args) ++ [wamp_service_utils:options(ArgsKw)]) catch %% @TODO review error handling and URIs - Class:Reason -> - _ = lager:error("Error ~p:~p subscription handler=~p args=~p args_kw=~p stacktrace=~p", - [Class, Reason, Handler, Args, ArgsKw, erlang:get_stacktrace()]) + Class:Reason:Stacktrace -> + _ = ?LOG_ERROR("Error ~p:~p subscription handler=~p args=~p args_kw=~p stacktrace=~p", + [Class, Reason, Handler, Args, ArgsKw, Stacktrace]) end. %% @private @@ -178,31 +189,51 @@ handle_result(Conn, RequestId, Details, Res, ArgsKw) -> end. %% @private -handle_invocation_error(Conn, RequestId, Handler, Class, Reason) -> +handle_invocation_error(Conn, RequestId, Handler, Class, Reason, Stacktrace) -> case {Class, Reason} of %% @TODO review error handling and URIs {throw, unauthorized} -> - Error = #{code => unauthorized, message => _(<<"Unauthorized user.">>), - description => _(<<"The user does not have the required permissions to access the resource.">>)}, - awre:error(Conn, RequestId, Error, <<"wamp.error.unauthorized">>); + Error = #{ + code => unauthorized, + message => <<"Unauthorized user.">>, + description => <<"The user does not have the required permissions to access the resource.">> + }, + awre:error( + Conn, RequestId, Error, <<"wamp.error.unauthorized">>, [], #{} + ); {throw, not_found} -> - Error = #{code => not_found, message => _(<<"Resource not found.">>), - description => _(<<"The resource you are trying to retrieve does not exist.">>)}, - awre:error(Conn, RequestId, Error, <<"com.magenta.error.not_found">>); - {_, {error, Key, Error}} -> - awre:error(Conn, RequestId, Error, Key); + Error = #{ + code => not_found, + message => <<"Resource not found.">>, + description => <<"The resource you are trying to retrieve does not exist.">> + }, + awre:error( + Conn, RequestId, Error, + <<"com.magenta.error.not_found">>, [], #{} + ); + {_, {error, Uri, Error}} -> + awre:error(Conn, RequestId, Error, Uri, [], #{}); {error, #{code := authorization_error} = Error} -> - awre:error(Conn, RequestId, Error, <<"wamp.error.not_authorized">>); + awre:error(Conn, RequestId, Error, <<"wamp.error.not_authorized">>, [], #{}); {error, #{code := service_error} = Error} -> - awre:error(Conn, RequestId, Error, <<"com.magenta.error.internal_error">>); - {error, #{code := _} = Error} -> - awre:error(Conn, RequestId, Error, <<"wamp.error.invalid_argument">>); + awre:error(Conn, RequestId, Error, <<"com.magenta.error.internal_error">>, [], #{}); + {error, #{code := <<"com.magenta.", _/binary>> = Uri} = Error} -> + awre:error(Conn, RequestId, Error, Uri, [], #{}); + {error, #{code := <<"wamp.", _/binary>> = Uri} = Error} -> + awre:error(Conn, RequestId, Error, Uri, [], #{}); + {error, #{code := Code} = Error} when is_atom(Code); is_binary(Code) -> + awre:error(Conn, RequestId, Error, <<"wamp.error.invalid_argument">>, [], #{}); {Class, Reason} -> - _ = lager:error("handle invocation error: handler=~p, class=~p, reason=~p, stack=~p", - [Handler, Class, Reason, erlang:get_stacktrace()]), - Error = #{code => internal_error, message => _(<<"Internal error.">>), - description => _(<<"There was an internal error, please contact the administrator.">>)}, - awre:error(Conn, RequestId, Error, <<"com.magenta.error.internal_error">>) + _ = ?LOG_ERROR( + "handle invocation error: handler=~p, class=~p, reason=~p, stack=~p", + [Handler, Class, Reason, Stacktrace] + ), + Error = #{ + code => internal_error, + message => <<"Internal error.">>, + description => <<"There was an internal error, please contact the administrator.">> + }, + awre:error(Conn, RequestId, Error, <<"com.magenta.error.internal_error">>, [], #{}) end. exec_callback({Mod, Fun}, Args) -> @@ -221,7 +252,7 @@ handle_security(_, _) -> register_callbacks(State = #{cb_conf := CbConf}) -> maps:fold(fun (Uri, Cb, St) -> add_callback(Uri, Cb, St) - end, State#{cb_conf => #{}, callbacks => #{} ,inverted_ref => #{}}, CbConf). + end, State#{cb_conf => #{}, callbacks => #{}, inverted_ref => #{}}, CbConf). normalize_cb_conf(CbConf = #{}) -> CbConf; @@ -239,10 +270,10 @@ normalize_cb_conf(CbConf) when is_list(CbConf) -> add_callback(Uri, Callback = {procedure, Fun, Scopes}, State = #{cb_conf := CbConf, callbacks := Callbacks, inverted_ref := InvertedRef, conn := Conn}) -> - _ = lager:info("registering procedure uri=~p ... ", [Uri]), + _ = ?LOG_INFO("registering procedure uri=~p ... ", [Uri]), ok = validate_handler(Fun), {ok, RegistrationId} = awre:register(Conn, [{invoke, roundrobin}], Uri), - _ = lager:info("registered reg_id=~p.", [RegistrationId]), + _ = ?LOG_INFO("registered reg_id=~p.", [RegistrationId]), State#{ cb_conf => CbConf#{Uri => Callback}, callbacks => Callbacks#{RegistrationId => #{uri => Uri, handler => Fun, scopes => Scopes}}, @@ -251,10 +282,10 @@ add_callback(Uri, Callback = {procedure, Fun, Scopes}, add_callback(Uri, Callback = {subscription, Fun}, State = #{cb_conf := CbConf, callbacks := Callbacks, inverted_ref := InvertedRef, conn := Conn}) -> - _ = lager:info("registering subscription uri=~p ... ", [Uri]), + _ = ?LOG_INFO("registering subscription uri=~p ... ", [Uri]), ok = validate_handler(Fun), {ok, SubscriptionId} = awre:subscribe(Conn, [], Uri), - _ = lager:info("registered subs_id=~p.", [SubscriptionId]), + _ = ?LOG_INFO("registered subs_id=~p.", [SubscriptionId]), State#{ cb_conf => CbConf#{Uri => Callback}, callbacks => Callbacks#{SubscriptionId => #{uri => Uri, handler => Fun}}, @@ -262,10 +293,10 @@ add_callback(Uri, Callback = {subscription, Fun}, }. remove_callback(Uri, State = #{inverted_ref := InvertedRef}) -> - _ = lager:debug("deregistering procedure uri=~p ... ", [Uri]), + _ = ?LOG_DEBUG("deregistering procedure uri=~p ... ", [Uri]), case maps:get(Uri, InvertedRef, undefined) of undefined -> - _ = lager:warning("Attemping to remove invalid registration uri=~p", [Uri]), + _ = ?LOG_WARNING("Attemping to remove invalid registration uri=~p", [Uri]), State; _ -> #{inverted_ref := InvertedRef = #{Uri := Id}, callbacks := Callbacks, @@ -277,10 +308,10 @@ remove_callback(Uri, State = #{inverted_ref := InvertedRef}) -> end. do_remove_callback(Conn, Id, {procedure, _, _}) -> - _ = lager:debug("deregistering procedure id=~p ... ", [Id]), + _ = ?LOG_DEBUG("deregistering procedure id=~p ... ", [Id]), awre:unregister(Conn, Id); do_remove_callback(Conn, Id, {subscription, _}) -> - _ = lager:debug("deregistering subscription id=~p ... ", [Id]), + _ = ?LOG_DEBUG("deregistering subscription id=~p ... ", [Id]), awre:unsubscribe(Conn, Id). validate_handler(Fun) when is_function(Fun) -> @@ -289,13 +320,13 @@ validate_handler(Handler = {M, F}) -> Exports = M:module_info(exports), case lists:keyfind(F, 1, Exports) of false -> - _ = lager:error("Invalid handler ~p", [Handler]), + _ = ?LOG_ERROR("Invalid handler ~p", [Handler]), error(invalid_handler, "The handler you're trying to register does not exist."); _ -> ok end; validate_handler(Handler) -> - _ = lager:error("Invalid handler ~p", [Handler]), + _ = ?LOG_ERROR("Invalid handler ~p", [Handler]), error(invalid_handler, <<"The handler you're trying to register is invalid", "(should be either Fun | {Mod, FunName}).">>). @@ -324,9 +355,11 @@ do_connect(State) -> State2 = register_callbacks(State1), {ok, State2} catch - Class:Reason -> - _ = lager:error("Connection error class=~p reason=~p stacktarce=~p", - [Class, Reason, erlang:get_stacktrace()]), + Class:Reason:Stacktrace -> + _ = ?LOG_ERROR( + "Connection error class=~p reason=~p stacktarce=~p", + [Class, Reason, Stacktrace] + ), {error, Class} end. @@ -334,7 +367,7 @@ do_reconnect(State) -> #{cbackoff := CBackoff, attempts := Attempts, retries := Retries} = State, case Attempts =< Retries of false -> - _ = lager:error("Failed to reconnect :-("), + _ = ?LOG_ERROR("Failed to reconnect :-("), exit(wamp_connection_error); true -> case do_connect(State) of @@ -342,7 +375,7 @@ do_reconnect(State) -> {ok, State1}; {error, _} -> {Time, CBackoff1} = backoff:fail(CBackoff), - _ = lager:info("Reconnecting, attempt ~p of ~p failed (retry in ~ps) ...", + _ = ?LOG_INFO("Reconnecting, attempt ~p of ~p failed (retry in ~ps) ...", [Attempts, Retries, Time/1000]), timer:sleep(Time), do_reconnect(State#{attempts => Attempts + 1, cbackoff => CBackoff1}) diff --git a/src/wamp_service_instr.erl b/src/wamp_service_instr.erl index 2106d3e..f76be85 100644 --- a/src/wamp_service_instr.erl +++ b/src/wamp_service_instr.erl @@ -14,5 +14,5 @@ ping(_ArgsKw) -> -spec log_level(binary(), map()) -> undefined. log_level(Level, _ArgsKw) -> L = binary_to_existing_atom(Level, utf8), - lager:set_loglevel(lager_console_backend, L), + logger:set_application_level(wamp_service, L), undefined. diff --git a/src/wamp_service_service.erl b/src/wamp_service_service.erl index 8706c18..9fc38d0 100644 --- a/src/wamp_service_service.erl +++ b/src/wamp_service_service.erl @@ -5,6 +5,8 @@ -behaviour(gen_server). +-include_lib("kernel/include/logger.hrl"). + -export([start_link/1]). %% gen_server callbacks @@ -13,7 +15,8 @@ start_link(Opts) -> - gen_server:start_link({local, wamp_caller} ,?MODULE, Opts, []). + gen_server:start_link({local, wamp_caller}, ?MODULE, Opts, []). + %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | @@ -24,14 +27,17 @@ start_link(Opts) -> %%-------------------------------------------------------------------- init(Opts) -> process_flag(trap_exit, true), + Host = proplists:get_value(hostname, Opts), Port = proplists:get_value(port, Opts), Realm = proplists:get_value(realm, Opts), Encoding = proplists:get_value(encoding, Opts), - Retries = proplists:get_value(retries, Opts, 10), - InitBackoff = proplists:get_value(backoff, Opts, 500), - Backoff = backoff:init(InitBackoff, 120000), - Reconnect = proplists:get_value(reconnect, Opts, false), + + %% reconnect options + Reconnect = wamp_service_utils:reconnect(Opts), + Retries = wamp_service_utils:reconnect_retries(Opts), + Backoff = wamp_service_utils:init_backoff(Reconnect, Opts), + State = #{host => Host, port => Port, realm => Realm, encoding => Encoding, retries => Retries, backoff => Backoff, reconnect => Reconnect}, @@ -106,8 +112,9 @@ do_call({call, Uri, Args, ArgsKw, Timeout}, From, #{conn := Conn}) Res = awre:call(Conn, [{timeout, Timeout}], Uri, Args, ArgsKw1, Timeout + 50), gen_server:reply(From, Res) catch - Class:Reason -> - handle_call_error(Class, Reason, Uri, Args, ArgsKw1) + Class:Reason:Stacktrace -> + handle_call_error( + Class, Reason, Stacktrace, Uri, Args, ArgsKw1) end end). @@ -121,7 +128,7 @@ do_publish({publish, Topic, Args, Opts}, #{conn := Conn}) -> do_publish2({publish2, Topic, Opts, Args, KWArgs}, #{conn := Conn}) -> Opts1 = set_trace_id(Opts), %% Awre wants a proplist, not a map - PL = maps:to_list(Opts), + PL = maps:to_list(Opts1), spawn( fun() -> awre:publish(Conn, PL, Topic, Args, KWArgs) @@ -129,19 +136,27 @@ do_publish2({publish2, Topic, Opts, Args, KWArgs}, #{conn := Conn}) -> ). -handle_call_error(Class, Reason, Uri, Args, Opts) -> - _ = lager:error("handle call class=~p, reason=~p, uri=~p, args=~p, args_kw=~p, stacktrace=~p", - [Class, Reason, Uri, Args, Opts, erlang:get_stacktrace()]), +handle_call_error(Class, Reason, Stacktrace, Uri, Args, Opts) -> + _ = ?LOG_ERROR( + "handle call class=~p, reason=~p, uri=~p, args=~p, args_kw=~p, stacktrace=~p", + [Class, Reason, Uri, Args, Opts, Stacktrace] + ), case {Class, Reason} of {exit, {timeout, _}} -> - Details = #{code => timeout, message => _(<<"Service timeout.">>), - description => _(<<"There was a timeout resolving the operation.">>)}, + Details = #{ + code => timeout, + message => <<"Service timeout.">>, + description => <<"There was a timeout resolving the operation.">> + }, {error, #{}, <<"com.magenta.error.timeout">>, #{}, Details}; {error, #{code := _} = Error} -> Error; {_, _} -> - Details = #{code => internal_error, message => _(<<"Internal error.">>), - description => _(<<"There was an internal error, please contact the administrator.">>)}, + Details = #{ + code => internal_error, + message => <<"Internal error.">>, + description => <<"There was an internal error, please contact the administrator.">> + }, {error, #{}, <<"com.magenta.error.internal">>, #{}, Details} end. @@ -167,13 +182,20 @@ do_connect(State) -> #{backoff := Backoff} = State, {ok, SessionId, RouterDetails} = awre:connect(Conn, Host, Port, Realm, Encoding), link(Conn), - State1 = State#{conn => Conn, session_id => SessionId, details => RouterDetails, - attempts => 1, cbackoff => Backoff}, + State1 = State#{ + conn => Conn, + session_id => SessionId, + details => RouterDetails, + attempts => 1, + cbackoff => Backoff + }, {ok, State1} catch - Class:Reason -> - _ = lager:error("Connection error class=~p reason=~p stacktarce=~p", - [Class, Reason, erlang:get_stacktrace()]), + Class:Reason:Stacktrace -> + _ = ?LOG_ERROR( + "Connection error class=~p reason=~p stacktarce=~p", + [Class, Reason, Stacktrace] + ), {error, Class} end. @@ -181,7 +203,7 @@ do_reconnect(State) -> #{cbackoff := CBackoff, attempts := Attempts, retries := Retries} = State, case Attempts =< Retries of false -> - _ = lager:error("Failed to reconnect :-("), + _ = ?LOG_ERROR("Failed to reconnect"), exit(wamp_connection_error); true -> {Time, CBackoff1} = backoff:fail(CBackoff), @@ -189,8 +211,10 @@ do_reconnect(State) -> {ok, State1} -> {ok, State1}; {error, _} -> - _ = lager:info("Reconnecting, attempt ~p of ~p failed (retry in ~ps) ...", - [Attempts, Retries, Time/1000]), + _ = ?LOG_INFO( + "Reconnecting, attempt ~p of ~p failed (retry in ~ps) ...", + [Attempts, Retries, Time/1000] + ), timer:sleep(Time), do_reconnect(State#{attempts => Attempts + 1, cbackoff => CBackoff1}) end diff --git a/src/wamp_service_utils.erl b/src/wamp_service_utils.erl index 7bec117..c6fbef2 100644 --- a/src/wamp_service_utils.erl +++ b/src/wamp_service_utils.erl @@ -3,16 +3,180 @@ %% ============================================================================= -module(wamp_service_utils). --export([options/1, args/1]). +-export([args/1]). +-export([init_backoff/1]). +-export([init_backoff/2]). +-export([options/1]). +-export([reconnect_backoff_max/1]). +-export([reconnect_backoff_max/2]). +-export([reconnect_backoff_min/1]). +-export([reconnect_backoff_min/2]). +-export([reconnect_backoff_type/1]). +-export([reconnect_backoff_type/2]). +-export([reconnect_retries/1]). +-export([reconnect_retries/2]). +-export([reconnect/1]). +-export([reconnect/2]). + + + +%% ============================================================================= +%% API +%% ============================================================================= + + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- options(undefined) -> #{}; + options(ArgsKw) when is_map(ArgsKw) -> ArgsKw. + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- args(undefined) -> []; + args(Args) when is_list(Args) -> Args; + args(Arg) -> [Arg]. + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec init_backoff(boolean(), proplist:proplist()) -> backoff:backoff() | undefined. + +init_backoff(false, _Opts) -> + undefined; + +init_backoff(true, Opts) -> + init_backoff(Opts). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec init_backoff(proplist:proplist()) -> backoff:backoff(). + +init_backoff(Opts) -> + Min = reconnect_backoff_min(Opts), + Max = reconnect_backoff_max(Opts), + Type = reconnect_backoff_type(Opts), + backoff:type(backoff:init(Min, Max), Type). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect(proplist:proplist()) -> non_neg_integer(). + +reconnect(Opts) -> + reconnect(Opts, false). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect(proplist:proplist(), boolean()) -> boolean(). + +reconnect(Opts, Default) -> + proplists:get_value(reconnect, Opts, Default). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_retries(proplist:proplist()) -> non_neg_integer(). + +reconnect_retries(Opts) -> + reconnect_retries(Opts, 10). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_retries(proplist:proplist(), non_neg_integer()) -> non_neg_integer(). + +reconnect_retries(Opts, Default) -> + %% to be compatible with previuos versions + Retries = proplists:get_value(retries, Opts, Default), + proplists:get_value(reconnect_retries, Opts, Retries). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_backoff_min(proplist:proplist()) -> non_neg_integer(). + +reconnect_backoff_min(Opts) -> + reconnect_backoff_min(Opts, 500). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_backoff_min(proplist:proplist(), non_neg_integer()) -> non_neg_integer(). + +reconnect_backoff_min(Opts, Default) -> + %% to be compatible with previuos versions + InitBackoff = proplists:get_value(backoff, Opts, Default), + proplists:get_value(reconnect_backoff_min, Opts, InitBackoff). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_backoff_max(proplist:proplist()) -> non_neg_integer(). + +reconnect_backoff_max(Opts) -> + reconnect_backoff_max(Opts, 60000). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_backoff_max(proplist:proplist(), non_neg_integer()) -> non_neg_integer(). + +reconnect_backoff_max(Opts, Default) -> + proplists:get_value(reconnect_backoff_max, Opts, Default). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_backoff_type(proplist:proplist()) -> non_neg_integer(). + +reconnect_backoff_type(Opts) -> + reconnect_backoff_type(Opts, jitter). + + +%% ----------------------------------------------------------------------------- +%% @doc +%% @end +%% ----------------------------------------------------------------------------- +-spec reconnect_backoff_type(proplist:proplist(), jitter | normal) -> non_neg_integer(). + +reconnect_backoff_type(Opts, Default) -> + proplists:get_value(reconnect_backoff_type, Opts, Default). \ No newline at end of file diff --git a/test/wamp_service_SUITE.erl b/test/wamp_service_SUITE.erl index 30a5845..d74c037 100644 --- a/test/wamp_service_SUITE.erl +++ b/test/wamp_service_SUITE.erl @@ -27,8 +27,6 @@ end_per_group(_, _Config) -> ok. init_per_suite(Config) -> - {ok, _} = application:ensure_all_started(lager), - lager_common_test_backend:bounce(debug), {ok, _} = application:ensure_all_started(wamp_service), timer:sleep(2000), Config. @@ -46,8 +44,12 @@ multiple_results_test(_) -> circular_test(_) -> - Ref = rand:uniform(), - {ok, Ref} = wamp_service:call(<<"com.example.circular">>, [Ref], #{}). + %% Ref = rand:uniform(), + Ref = rand:uniform(1 bsl 64), + ?assertEqual( + {ok, Ref}, + wamp_service:call(<<"com.example.circular">>, [Ref], #{}) + ). circular_service_error(_) -> {error, <<"com.magenta.error.internal_error">>, _} = @@ -60,7 +62,9 @@ notfound_error_test(_) -> {error, <<"com.magenta.error.not_found">>, _} = wamp_service:call(<<"com.example.notfound_error">>, [], #{}). validation_error_test(_) -> - {error, <<"wamp.error.invalid_argument">>, _} = wamp_service:call(<<"com.example.validation_error">>, [], #{}). + Expected = <<"wamp.error.invalid_argument">>, + Result = wamp_service:call(<<"com.example.validation_error">>, [], #{}), + ?assertEqual(Expected, element(2, Result)). service_error_test(_) -> {error, <<"com.magenta.error.internal_error">>, _} = wamp_service:call(<<"com.example.service_error">>, [], #{}).