From 02ed2148d74e7472f742936a245e00cb07a07883 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Tue, 15 Mar 2022 10:27:58 +0800 Subject: [PATCH] refactor: move api `top` -> `front`, `bottom` -> `rear` --- apps/emqx/include/emqx_authentication.hrl | 4 +-- apps/emqx/src/emqx_authentication.erl | 6 ++-- apps/emqx/src/emqx_authentication_config.erl | 4 +-- apps/emqx/test/emqx_authentication_SUITE.erl | 17 ++++++---- apps/emqx_authn/src/emqx_authn_api.erl | 16 +++++----- apps/emqx_authn/test/emqx_authn_api_SUITE.erl | 8 ++--- apps/emqx_authz/include/emqx_authz.hrl | 4 +-- apps/emqx_authz/src/emqx_authz.erl | 4 +-- .../emqx_authz/src/emqx_authz_api_sources.erl | 25 ++++++++------- apps/emqx_authz/test/emqx_authz_SUITE.erl | 8 ++--- .../test/emqx_authz_api_sources_SUITE.erl | 4 +-- apps/emqx_exhook/include/emqx_exhook.hrl | 5 +++ apps/emqx_exhook/src/emqx_exhook_api.erl | 32 ++++++++++--------- apps/emqx_exhook/src/emqx_exhook_mgr.erl | 8 ++--- .../test/emqx_exhook_api_SUITE.erl | 10 +++--- .../src/emqx_mgmt_api_plugins.erl | 20 ++++++------ 16 files changed, 94 insertions(+), 81 deletions(-) diff --git a/apps/emqx/include/emqx_authentication.hrl b/apps/emqx/include/emqx_authentication.hrl index 4729225cf..dc501d1d8 100644 --- a/apps/emqx/include/emqx_authentication.hrl +++ b/apps/emqx/include/emqx_authentication.hrl @@ -29,8 +29,8 @@ -define(EMQX_AUTHENTICATION_SCHEMA_MODULE_PT_KEY, emqx_authentication_schema_module). %% authentication move cmd --define(CMD_MOVE_TOP, top). --define(CMD_MOVE_BOTTOM, bottom). +-define(CMD_MOVE_FRONT, front). +-define(CMD_MOVE_REAR, rear). -define(CMD_MOVE_BEFORE(Before), {before, Before}). -define(CMD_MOVE_AFTER(After), {'after', After}). diff --git a/apps/emqx/src/emqx_authentication.erl b/apps/emqx/src/emqx_authentication.erl index bb191e0a2..5df50a427 100644 --- a/apps/emqx/src/emqx_authentication.erl +++ b/apps/emqx/src/emqx_authentication.erl @@ -100,7 +100,7 @@ -type chain_name() :: atom(). -type authenticator_id() :: binary(). --type position() :: top | bottom | {before, authenticator_id()} | {'after', authenticator_id()}. +-type position() :: front | rear | {before, authenticator_id()} | {'after', authenticator_id()}. -type authn_type() :: atom() | {atom(), atom()}. -type provider() :: module(). @@ -695,9 +695,9 @@ do_move_authenticator(ID, Authenticators, Position) -> {error, {not_found, {authenticator, ID}}}; {value, Authenticator, NAuthenticators} -> case Position of - ?CMD_MOVE_TOP -> + ?CMD_MOVE_FRONT -> {ok, [Authenticator | NAuthenticators]}; - ?CMD_MOVE_BOTTOM -> + ?CMD_MOVE_REAR -> {ok, NAuthenticators ++ [Authenticator]}; ?CMD_MOVE_BEFORE(RelatedID) -> insert(Authenticator, NAuthenticators, ?CMD_MOVE_BEFORE(RelatedID), []); diff --git a/apps/emqx/src/emqx_authentication_config.erl b/apps/emqx/src/emqx_authentication_config.erl index e30002f5a..66f96fc76 100644 --- a/apps/emqx/src/emqx_authentication_config.erl +++ b/apps/emqx/src/emqx_authentication_config.erl @@ -89,9 +89,9 @@ do_pre_config_update({move_authenticator, _ChainName, AuthenticatorID, Position} {error, Reason} -> {error, Reason}; {ok, BeforeFound, [Found | AfterFound]} -> case Position of - ?CMD_MOVE_TOP -> + ?CMD_MOVE_FRONT -> {ok, [Found | BeforeFound] ++ AfterFound}; - ?CMD_MOVE_BOTTOM -> + ?CMD_MOVE_REAR -> {ok, BeforeFound ++ AfterFound ++ [Found]}; ?CMD_MOVE_BEFORE(BeforeRelatedID) -> case split_by_id(BeforeRelatedID, BeforeFound ++ AfterFound) of diff --git a/apps/emqx/test/emqx_authentication_SUITE.erl b/apps/emqx/test/emqx_authentication_SUITE.erl index 7c3a7fecd..1a3ebb5e4 100644 --- a/apps/emqx/test/emqx_authentication_SUITE.erl +++ b/apps/emqx/test/emqx_authentication_SUITE.erl @@ -185,14 +185,17 @@ t_authenticator(Config) when is_list(Config) -> % Move authenticator ?assertMatch({ok, [#{id := ID1}, #{id := ID2}]}, ?AUTHN:list_authenticators(ChainName)), - ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, top)), + ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, ?CMD_MOVE_FRONT)), ?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(ChainName)), - ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, bottom)), + ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, ?CMD_MOVE_REAR)), ?assertMatch({ok, [#{id := ID1}, #{id := ID2}]}, ?AUTHN:list_authenticators(ChainName)), - ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, {before, ID1})), - ?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(ChainName)); + ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, ?CMD_MOVE_BEFORE(ID1))), + ?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(ChainName)), + + ?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, ?CMD_MOVE_AFTER(ID1))), + ?assertMatch({ok, [#{id := ID1}, #{id := ID2}]}, ?AUTHN:list_authenticators(ChainName)); t_authenticator({'end', Config}) -> ?AUTHN:delete_chain(test), @@ -211,7 +214,7 @@ t_authenticate(Config) when is_list(Config) -> listener => ListenerID, protocol => mqtt, username => <<"good">>, - password => <<"any">>}, + password => <<"any">>}, ?assertEqual({ok, #{is_superuser => false}}, emqx_access_control:authenticate(ClientInfo)), register_provider(AuthNType, ?MODULE), @@ -291,7 +294,7 @@ t_update_config(Config) when is_list(Config) -> ?assertMatch( {ok, _}, - update_config([?CONF_ROOT], {move_authenticator, Global, ID2, top})), + update_config([?CONF_ROOT], {move_authenticator, Global, ID2, ?CMD_MOVE_FRONT})), ?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(Global)), @@ -344,7 +347,7 @@ t_update_config(Config) when is_list(Config) -> ?assertMatch( {ok, _}, - update_config(ConfKeyPath, {move_authenticator, ListenerID, ID2, top})), + update_config(ConfKeyPath, {move_authenticator, ListenerID, ID2, ?CMD_MOVE_FRONT})), ?assertMatch( {ok, [#{id := ID2}, #{id := ID1}]}, diff --git a/apps/emqx_authn/src/emqx_authn_api.erl b/apps/emqx_authn/src/emqx_authn_api.erl index 6b53ebb5a..2266abfb2 100644 --- a/apps/emqx_authn/src/emqx_authn_api.erl +++ b/apps/emqx_authn/src/emqx_authn_api.erl @@ -1059,10 +1059,10 @@ serialize_error(Reason) -> {400, #{code => <<"BAD_REQUEST">>, message => binfmt("~p", [Reason])}}. -parse_position(<<"top">>) -> - {ok, ?CMD_MOVE_TOP}; -parse_position(<<"bottom">>) -> - {ok, ?CMD_MOVE_BOTTOM}; +parse_position(<<"front">>) -> + {ok, ?CMD_MOVE_FRONT}; +parse_position(<<"rear">>) -> + {ok, ?CMD_MOVE_REAR}; parse_position(<<"before:">>) -> {error, {invalid_parameter, position}}; parse_position(<<"after:">>) -> @@ -1205,16 +1205,16 @@ request_user_update_examples() -> request_move_examples() -> #{ - move_to_top => #{ + move_to_front => #{ summary => <<"Move authenticator to the beginning of the chain">>, value => #{ - position => <<"top">> + position => <<"front">> } }, - move_to_bottom => #{ + move_to_rear => #{ summary => <<"Move authenticator to the end of the chain">>, value => #{ - position => <<"bottom">> + position => <<"rear">> } }, 'move_before_password_based:built_in_database' => #{ diff --git a/apps/emqx_authn/test/emqx_authn_api_SUITE.erl b/apps/emqx_authn/test/emqx_authn_api_SUITE.erl index ce4912f03..a707dfeb4 100644 --- a/apps/emqx_authn/test/emqx_authn_api_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_api_SUITE.erl @@ -376,11 +376,11 @@ test_authenticator_move(PathPrefix) -> %% Valid moves - %% test top + %% test front {ok, 204, _} = request( post, uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]), - #{position => <<"top">>}), + #{position => <<"front">>}), ?assertAuthenticatorsMatch( [ @@ -390,11 +390,11 @@ test_authenticator_move(PathPrefix) -> ], PathPrefix ++ [?CONF_NS]), - %% test bottom + %% test rear {ok, 204, _} = request( post, uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]), - #{position => <<"bottom">>}), + #{position => <<"rear">>}), ?assertAuthenticatorsMatch( [ diff --git a/apps/emqx_authz/include/emqx_authz.hrl b/apps/emqx_authz/include/emqx_authz.hrl index 245f19c1f..13c100ba8 100644 --- a/apps/emqx_authz/include/emqx_authz.hrl +++ b/apps/emqx_authz/include/emqx_authz.hrl @@ -34,8 +34,8 @@ -define(CMD_APPEND, append). -define(CMD_MOVE, move). --define(CMD_MOVE_TOP, top). --define(CMD_MOVE_BOTTOM, bottom). +-define(CMD_MOVE_FRONT, front). +-define(CMD_MOVE_REAR, rear). -define(CMD_MOVE_BEFORE(Before), {before, Before}). -define(CMD_MOVE_AFTER(After), {'after', After}). diff --git a/apps/emqx_authz/src/emqx_authz.erl b/apps/emqx_authz/src/emqx_authz.erl index 4ff06f697..b270176ec 100644 --- a/apps/emqx_authz/src/emqx_authz.erl +++ b/apps/emqx_authz/src/emqx_authz.erl @@ -127,10 +127,10 @@ update({?CMD_DELETE, Type}, Sources) -> update(Cmd, Sources) -> emqx_authz_utils:update_config(?CONF_KEY_PATH, {Cmd, Sources}). -do_update({?CMD_MOVE, Type, ?CMD_MOVE_TOP}, Conf) when is_list(Conf) -> +do_update({?CMD_MOVE, Type, ?CMD_MOVE_FRONT}, Conf) when is_list(Conf) -> {Source, Front, Rear} = take(Type, Conf), [Source | Front] ++ Rear; -do_update({?CMD_MOVE, Type, ?CMD_MOVE_BOTTOM}, Conf) when is_list(Conf) -> +do_update({?CMD_MOVE, Type, ?CMD_MOVE_REAR}, Conf) when is_list(Conf) -> {Source, Front, Rear} = take(Type, Conf), Front ++ Rear ++ [Source]; do_update({?CMD_MOVE, Type, ?CMD_MOVE_BEFORE(Before)}, Conf) when is_list(Conf) -> diff --git a/apps/emqx_authz/src/emqx_authz_api_sources.erl b/apps/emqx_authz/src/emqx_authz_api_sources.erl index bddfddb49..58eed9982 100644 --- a/apps/emqx_authz/src/emqx_authz_api_sources.erl +++ b/apps/emqx_authz/src/emqx_authz_api_sources.erl @@ -477,10 +477,10 @@ parameters_field() -> } ]. -parse_position(<<"top">>) -> - {ok, ?CMD_MOVE_TOP}; -parse_position(<<"bottom">>) -> - {ok, ?CMD_MOVE_BOTTOM}; +parse_position(<<"front">>) -> + {ok, ?CMD_MOVE_FRONT}; +parse_position(<<"rear">>) -> + {ok, ?CMD_MOVE_REAR}; parse_position(<<"before:", Before/binary>>) -> {ok, ?CMD_MOVE_BEFORE(Before)}; parse_position(<<"after:", After/binary>>) -> @@ -493,15 +493,18 @@ parse_position(_) -> {error, {invalid_parameter, position}}. position_example() -> - #{ top => - #{ summary => <<"top example">> - , value => #{<<"position">> => <<"top">>}} - , bottom => - #{ summary => <<"bottom example">> - , value => #{<<"position">> => <<"bottom">>}} - , relative => + #{ front => + #{ summary => <<"front example">> + , value => #{<<"position">> => <<"front">>}} + , rear => + #{ summary => <<"rear example">> + , value => #{<<"position">> => <<"rear">>}} + , relative_before => #{ summary => <<"relative example">> , value => #{<<"position">> => <<"before:file">>}} + , relative_after => + #{ summary => <<"relative example">> + , value => #{<<"position">> => <<"after:file">>}} }. authz_sources_types(Type) -> diff --git a/apps/emqx_authz/test/emqx_authz_SUITE.erl b/apps/emqx_authz/test/emqx_authz_SUITE.erl index e7b8be54e..0e73e44cf 100644 --- a/apps/emqx_authz/test/emqx_authz_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_SUITE.erl @@ -186,7 +186,7 @@ t_move_source(_) -> , #{type := file} ], emqx_authz:lookup()), - {ok, _} = emqx_authz:move(postgresql, top), + {ok, _} = emqx_authz:move(postgresql, ?CMD_MOVE_FRONT), ?assertMatch([ #{type := postgresql} , #{type := http} , #{type := mongodb} @@ -195,7 +195,7 @@ t_move_source(_) -> , #{type := file} ], emqx_authz:lookup()), - {ok, _} = emqx_authz:move(http, bottom), + {ok, _} = emqx_authz:move(http, ?CMD_MOVE_REAR), ?assertMatch([ #{type := postgresql} , #{type := mongodb} , #{type := mysql} @@ -204,7 +204,7 @@ t_move_source(_) -> , #{type := http} ], emqx_authz:lookup()), - {ok, _} = emqx_authz:move(mysql, {before, postgresql}), + {ok, _} = emqx_authz:move(mysql, ?CMD_MOVE_BEFORE(postgresql)), ?assertMatch([ #{type := mysql} , #{type := postgresql} , #{type := mongodb} @@ -213,7 +213,7 @@ t_move_source(_) -> , #{type := http} ], emqx_authz:lookup()), - {ok, _} = emqx_authz:move(mongodb, {'after', http}), + {ok, _} = emqx_authz:move(mongodb, ?CMD_MOVE_AFTER(http)), ?assertMatch([ #{type := mysql} , #{type := postgresql} , #{type := redis} diff --git a/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl b/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl index 4acc38dec..23daf1454 100644 --- a/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl @@ -318,7 +318,7 @@ t_move_source(_) -> ], emqx_authz:lookup()), {ok, 204, _} = request(post, uri(["authorization", "sources", "postgresql", "move"]), - #{<<"position">> => <<"top">>}), + #{<<"position">> => <<"front">>}), ?assertMatch([ #{type := postgresql} , #{type := http} , #{type := mongodb} @@ -327,7 +327,7 @@ t_move_source(_) -> ], emqx_authz:lookup()), {ok, 204, _} = request(post, uri(["authorization", "sources", "http", "move"]), - #{<<"position">> => <<"bottom">>}), + #{<<"position">> => <<"rear">>}), ?assertMatch([ #{type := postgresql} , #{type := mongodb} , #{type := mysql} diff --git a/apps/emqx_exhook/include/emqx_exhook.hrl b/apps/emqx_exhook/include/emqx_exhook.hrl index e478c8cc7..dd86833dc 100644 --- a/apps/emqx_exhook/include/emqx_exhook.hrl +++ b/apps/emqx_exhook/include/emqx_exhook.hrl @@ -45,3 +45,8 @@ ]). -endif. + +-define(CMD_MOVE_FRONT, {front, <<>>}). +-define(CMD_MOVE_REAR, {rear, <<>>}). +-define(CMD_MOVE_BEFORE(Before), {before, Before}). +-define(CMD_MOVE_AFTER(After), {'after', After}). diff --git a/apps/emqx_exhook/src/emqx_exhook_api.erl b/apps/emqx_exhook/src/emqx_exhook_api.erl index 6a81aee68..30510a457 100644 --- a/apps/emqx_exhook/src/emqx_exhook_api.erl +++ b/apps/emqx_exhook/src/emqx_exhook_api.erl @@ -18,6 +18,7 @@ -behaviour(minirest_api). +-include("emqx_exhook.hrl"). -include_lib("typerefl/include/types.hrl"). -include_lib("emqx/include/logger.hrl"). @@ -104,8 +105,9 @@ schema("/exhooks/:name/hooks") -> schema("/exhooks/:name/move") -> #{'operationId' => move, post => #{tags => ?TAGS, - description => <<"Move the server.\n" - "NOTE: The position should be \"top|bottom|before:{name}\"\n">>, + description => + <<"Move the server.\n", + "NOTE: The position should be \"front|rear|before:{name}|after:{name}\"\n">>, parameters => params_server_name_in_path(), 'requestBody' => emqx_dashboard_swagger:schema_with_examples( ref(move_req), @@ -119,7 +121,7 @@ schema("/exhooks/:name/move") -> fields(move_req) -> [{position, mk(string(), #{ desc => <<"The target position to be moved.">> - , example => <<"top">>})}]; + , example => <<"front">>})}]; fields(detail_server_info) -> [ {metrics, mk(ref(metrics), #{})} @@ -401,12 +403,12 @@ call_cluster(Fun) -> %%-------------------------------------------------------------------- position_example() -> - #{ top => - #{ summary => <<"absolute position 'top'">> - , value => #{<<"position">> => <<"top">>}} - , bottom => - #{ summary => <<"absolute position 'bottom'">> - , value => #{<<"position">> => <<"bottom">>}} + #{ front => + #{ summary => <<"absolute position 'front'">> + , value => #{<<"position">> => <<"front">>}} + , rear => + #{ summary => <<"absolute position 'rear'">> + , value => #{<<"position">> => <<"rear">>}} , related_before => #{ summary => <<"relative position 'before'">> , value => #{<<"position">> => <<"before:default">>}} @@ -415,14 +417,14 @@ position_example() -> , value => #{<<"position">> => <<"after:default">>}} }. -parse_position(<<"top">>) -> - {ok, {top, <<>>}}; -parse_position(<<"bottom">>) -> - {ok, {bottom, <<>>}}; +parse_position(<<"front">>) -> + {ok, ?CMD_MOVE_FRONT}; +parse_position(<<"rear">>) -> + {ok, ?CMD_MOVE_REAR}; parse_position(<<"before:", Related/binary>>) -> - {ok, {before, Related}}; + {ok, ?CMD_MOVE_BEFORE(Related)}; parse_position(<<"after:", Related/binary>>) -> - {ok, {'after', Related}}; + {ok, ?CMD_MOVE_AFTER(Related)}; parse_position(<<"before:">>) -> {error, invalid_position}; parse_position(<<"after:">>) -> diff --git a/apps/emqx_exhook/src/emqx_exhook_mgr.erl b/apps/emqx_exhook/src/emqx_exhook_mgr.erl index c24765d6b..7c6859ded 100644 --- a/apps/emqx_exhook/src/emqx_exhook_mgr.erl +++ b/apps/emqx_exhook/src/emqx_exhook_mgr.erl @@ -74,8 +74,8 @@ -type server() :: server_options(). -type server_options() :: map(). --type move_direct() :: top - | bottom +-type move_direct() :: front + | rear | before | 'after'. @@ -475,10 +475,10 @@ move([Server | T], Name, Direct, ToName, HeadL) -> move([], _Name, _Direct, _ToName, _HeadL) -> not_found. -move_to(top, _, Server, ServerL) -> +move_to(front, _, Server, ServerL) -> [Server | ServerL]; -move_to(bottom, _, Server, ServerL) -> +move_to(rear, _, Server, ServerL) -> ServerL ++ [Server]; move_to(Direct, ToName, Server, ServerL) -> diff --git a/apps/emqx_exhook/test/emqx_exhook_api_SUITE.erl b/apps/emqx_exhook/test/emqx_exhook_api_SUITE.erl index 181a87f5d..47a453f1e 100644 --- a/apps/emqx_exhook/test/emqx_exhook_api_SUITE.erl +++ b/apps/emqx_exhook/test/emqx_exhook_api_SUITE.erl @@ -37,7 +37,7 @@ exhook { ">>). all() -> - [ t_list, t_get, t_add, t_move_top, t_move_bottom + [ t_list, t_get, t_add, t_move_front, t_move_rear , t_move_before, t_move_after, t_delete, t_hooks, t_update ]. @@ -133,18 +133,18 @@ t_add(Cfg) -> ?assertMatch([<<"default">>, <<"test1">>], emqx_exhook_mgr:running()). -t_move_top(_) -> +t_move_front(_) -> Result = request_api(post, api_path(["exhooks", "default", "move"]), "", auth_header_(), - #{position => <<"top">>}), + #{position => <<"front">>}), ?assertMatch({ok, <<>>}, Result), ?assertMatch([<<"default">>, <<"test1">>], emqx_exhook_mgr:running()). -t_move_bottom(_) -> +t_move_rear(_) -> Result = request_api(post, api_path(["exhooks", "default", "move"]), "", auth_header_(), - #{position => <<"bottom">>}), + #{position => <<"rear">>}), ?assertMatch({ok, <<>>}, Result), ?assertMatch([<<"test1">>, <<"default">>], emqx_exhook_mgr:running()). diff --git a/apps/emqx_management/src/emqx_mgmt_api_plugins.erl b/apps/emqx_management/src/emqx_mgmt_api_plugins.erl index c7c963626..d806c309e 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_plugins.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_plugins.erl @@ -199,11 +199,11 @@ fields(builder) -> {website, hoconsc:mk(string(), #{example => "www.emqx.com"})} ]; fields(position) -> - [{position, hoconsc:mk(hoconsc:union([top, bottom, binary()]), + [{position, hoconsc:mk(hoconsc:union([front, rear, binary()]), #{ desc => """ Enable auto-boot at position in the boot list, where Position could be - 'top', 'bottom', or 'before:other-vsn', 'after:other-vsn' + 'front', 'rear', or 'before:other-vsn', 'after:other-vsn' to specify a relative position. """, required => false @@ -221,13 +221,13 @@ fields(running_status) -> move_request_body() -> emqx_dashboard_swagger:schema_with_examples(hoconsc:ref(?MODULE, position), #{ - move_to_top => #{ - summary => <<"move plugin on the top">>, - value => #{position => <<"top">>} + move_to_front => #{ + summary => <<"move plugin on the front">>, + value => #{position => <<"front">>} }, - move_to_bottom => #{ - summary => <<"move plugin on the bottom">>, - value => #{position => <<"bottom">>} + move_to_rear => #{ + summary => <<"move plugin on the rear">>, + value => #{position => <<"rear">>} }, move_to_before => #{ summary => <<"move plugin before other plugins">>, @@ -350,8 +350,8 @@ return(_, {error, #{error := "bad_info_file", return := {enoent, _}, path := Pat return(_, {error, Reason}) -> {400, #{code => 'PARAM_ERROR', message => iolist_to_binary(io_lib:format("~p", [Reason]))}}. -parse_position(#{<<"position">> := <<"top">>}, _) -> front; -parse_position(#{<<"position">> := <<"bottom">>}, _) -> rear; +parse_position(#{<<"position">> := <<"front">>}, _) -> front; +parse_position(#{<<"position">> := <<"rear">>}, _) -> rear; parse_position(#{<<"position">> := <<"before:", Name/binary>>}, Name) -> {error, <<"Can't before:self">>}; parse_position(#{<<"position">> := <<"after:", Name/binary>>}, Name) ->