Skip to content

Commit

Permalink
Cleanup of some trunkstore code (2600hz#5432)
Browse files Browse the repository at this point in the history
- Handle timeout on views more gracefully
- Improve types and naming
  • Loading branch information
jamesaimonetti authored and k-anderson committed Jan 28, 2019
1 parent 5b8f210 commit 31b2a6c
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 113 deletions.
2 changes: 1 addition & 1 deletion applications/trunkstore/src/ts.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
,bleg_callid :: kz_term:api_ne_binary()
,acctid = <<>> :: binary()
,acctdb = <<>> :: binary()
,route_req_jobj = kz_json:new() :: kz_json:object()
,route_req_jobj = kz_json:new() :: kapi_route:req()
,ep_data = kz_json:new() :: kz_json:object() %% data for the endpoint, either an actual endpoint or an offnet request
,amqp_worker :: kz_term:api_pid()
,callctl_q :: kz_term:api_ne_binary()
Expand Down
22 changes: 11 additions & 11 deletions applications/trunkstore/src/ts_callflow.erl
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@

-export_type([state/0]).

-spec init(kz_json:object(), kz_term:api_binary() | kz_term:api_binaries()) ->
-spec init(kapi_route:req(), kz_term:api_binary() | kz_term:api_binaries()) ->
state() |
{'error', 'not_ts_account'}.
init(RouteReqJObj, Type) ->
CallID = kz_json:get_value(<<"Call-ID">>, RouteReqJObj),
CallID = kapi_route:call_id(RouteReqJObj),
kz_util:put_callid(CallID),
case is_trunkstore_acct(RouteReqJObj, Type) of
'false' ->
lager:info("request is not for a trunkstore account"),
{'error', 'not_ts_account'};
'true' ->
AccountId = kz_json:get_value([<<"Custom-Channel-Vars">>, <<"Account-ID">>], RouteReqJObj),
AccountId = kapi_route:account_id(RouteReqJObj),
#ts_callflow_state{aleg_callid=CallID
,route_req_jobj=RouteReqJObj
,acctid=AccountId
Expand Down Expand Up @@ -86,17 +86,17 @@ send_park(#ts_callflow_state{route_req_jobj=JObj
,{<<"Method">>, <<"park">>}
,{<<"From-Realm">>, kzd_accounts:fetch_realm(AccountId)}
,{<<"Custom-Channel-Vars">>, kz_json:get_json_value(<<"Custom-Channel-Vars">>, JObj, kz_json:new())}
,{<<"Custom-Application-Vars">>, kz_json:get_json_value(<<"Custom-Channel-Vars">>, JObj)}
,{<<"Custom-Application-Vars">>, kz_json:get_json_value(<<"Custom-Application-Vars">>, JObj)}
| kz_api:default_headers(get_worker_queue(State)
,?APP_NAME, ?APP_VERSION
)
],
lager:info("trunkstore knows how to route this call, sending park route response"),
kz_amqp_worker:relay_to(Worker, self()),
kz_amqp_worker:cast(Resp
,fun(API) -> kapi_route:publish_resp(kz_api:server_id(JObj), API) end
,Worker
),
_ = kz_amqp_worker:cast(Resp
,fun(API) -> kapi_route:publish_resp(kz_api:server_id(JObj), API) end
,Worker
),
wait_for_win(State, ?WAIT_FOR_WIN_TIMEOUT).

-spec wait_for_win(state(), pos_integer()) -> {'won' | 'lost', state()}.
Expand Down Expand Up @@ -304,16 +304,16 @@ send_command(#ts_callflow_state{amqp_worker=Worker}, Command, PubFun) ->
%%%-----------------------------------------------------------------------------
%%% Data access functions
%%%-----------------------------------------------------------------------------
-spec get_request_data(state()) -> kz_json:object().
-spec get_request_data(state()) -> kapi_route:req().
get_request_data(#ts_callflow_state{route_req_jobj=JObj}) -> JObj.

-spec get_custom_channel_vars(state()) -> kz_json:object().
get_custom_channel_vars(#ts_callflow_state{route_req_jobj=JObj}) ->
kz_json:get_value(<<"Custom-Channel-Vars">>, JObj, kz_json:new()).
kz_json:get_json_value(<<"Custom-Channel-Vars">>, JObj, kz_json:new()).

-spec get_custom_sip_headers(state()) -> kz_term:api_object().
get_custom_sip_headers(#ts_callflow_state{route_req_jobj=JObj}) ->
kz_json:get_value(<<"Custom-SIP-Headers">>, JObj).
kz_json:get_json_value(<<"Custom-SIP-Headers">>, JObj).

-spec set_endpoint_data(state(), kz_json:object()) -> state().
set_endpoint_data(State, Data) -> State#ts_callflow_state{ep_data=Data}.
Expand Down
71 changes: 38 additions & 33 deletions applications/trunkstore/src/ts_from_offnet.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@

-define(SERVER, ?MODULE).

-spec start_link(kz_json:object()) -> kz_types:startlink_ret().
-spec start_link(kapi_route:req()) -> kz_types:startlink_ret().
start_link(RouteReqJObj) ->
proc_lib:start_link(?SERVER, 'init', [self(), RouteReqJObj]).

-spec init(pid(), kz_json:object()) -> 'ok'.
-spec init(pid(), kapi_route:req()) -> 'ok'.
init(Parent, RouteReqJObj) ->
proc_lib:init_ack(Parent, {'ok', self()}),
start_amqp(ts_callflow:init(RouteReqJObj, ['undefined', <<"resource">>])).
Expand All @@ -33,10 +33,10 @@ start_amqp(State) ->

-spec endpoint_data(ts_callflow:state()) -> 'ok'.
endpoint_data(State) ->
JObj = ts_callflow:get_request_data(State),
try get_endpoint_data(State) of
{'endpoint', Endpoint} ->
proceed_with_endpoint(State, Endpoint, JObj)
RouteReq = ts_callflow:get_request_data(State),
proceed_with_endpoint(State, Endpoint, RouteReq)
catch
'throw':'no_did_found' ->
lager:info("call was not for a trunkstore number");
Expand All @@ -47,18 +47,13 @@ endpoint_data(State) ->
ts_callflow:cleanup_amqp(State)
end.

-spec proceed_with_endpoint(ts_callflow:state(), kz_json:object(), kz_json:object()) -> 'ok'.
proceed_with_endpoint(State, Endpoint, JObj) ->
-spec proceed_with_endpoint(ts_callflow:state(), kz_json:object(), kapi_route:req()) -> 'ok'.
proceed_with_endpoint(State, Endpoint, RouteReq) ->
CallID = ts_callflow:get_aleg_id(State),
'true' = kapi_dialplan:bridge_endpoint_v(Endpoint),

InceptionAccountId = kz_json:get_ne_binary_value([<<"Custom-Channel-Vars">>, <<"Inception-Account-ID">>], JObj),
MediaHandling = case 'undefined' =/= InceptionAccountId
orelse kz_json:is_false(<<"Bypass-Media">>, Endpoint)
of
'true' -> <<"process">>; %% bypass media is false, process media
'false' -> <<"bypass">>
end,
InceptionAccountId = kz_json:get_ne_binary_value([<<"Custom-Channel-Vars">>, <<"Inception-Account-ID">>], RouteReq),
MediaHandling = media_handling(InceptionAccountId, Endpoint),

Id = kz_json:get_ne_binary_value([<<"Custom-Channel-Vars">>, <<"Authorizing-ID">>], Endpoint),

Expand All @@ -68,15 +63,28 @@ proceed_with_endpoint(State, Endpoint, JObj) ->
,{<<"Dial-Endpoint-Method">>, <<"single">>}
,{<<"Call-ID">>, CallID}
,{<<"Custom-Channel-Vars">>, kz_json:from_list([{<<"Trunkstore-ID">>, Id}])}
| kz_api:default_headers(ts_callflow:get_worker_queue(State)
,<<"call">>, <<"command">>
,?APP_NAME, ?APP_VERSION
)
| default_command_headers(State)
],
State1 = ts_callflow:set_failover(State, kz_json:get_json_value(<<"Failover">>, Endpoint, kz_json:new())),
State2 = ts_callflow:set_endpoint_data(State1, Endpoint),
send_park(State2, Command).

-spec default_command_headers(ts_callflow:state()) -> kz_term:proplist().
default_command_headers(State) ->
kz_api:default_headers(ts_callflow:get_worker_queue(State)
,<<"call">>, <<"command">>
,?APP_NAME, ?APP_VERSION
).

-spec media_handling(kz_term:api_ne_binary(), kz_json:object()) -> kz_term:ne_binary().
media_handling('undefined', Endpoint) ->
case kz_json:is_true(<<"Bypass-Media">>, Endpoint) of
'false' -> <<"process">>;
'true' -> <<"bypass">>
end;
media_handling(_InceptionAccountId, _Endpoint) ->
<<"process">>.

-spec send_park(ts_callflow:state(), kz_term:proplist()) -> 'ok'.
send_park(State, Command) ->
case ts_callflow:send_park(State) of
Expand Down Expand Up @@ -128,10 +136,7 @@ send_privacy(State) ->
Command = [{<<"Application-Name">>, <<"privacy">>}
,{<<"Privacy-Mode">>, <<"full">>}
,{<<"Call-ID">>, CallID}
| kz_api:default_headers(ts_callflow:get_worker_queue(State)
,<<"call">>, <<"command">>
,?APP_NAME, ?APP_VERSION
)
| default_command_headers(State)
],
ts_callflow:send_command(State
,Command
Expand Down Expand Up @@ -192,10 +197,7 @@ try_failover_sip(State, SIPUri) ->
Command = [{<<"Call-ID">>, CallID}
,{<<"Application-Name">>, <<"bridge">>}
,{<<"Endpoints">>, [EndPoint]}
| kz_api:default_headers(ts_callflow:get_worker_queue(State)
,<<"call">>, <<"command">>
,?APP_NAME, ?APP_VERSION
)
| default_command_headers(State)
],
ts_callflow:send_command(State
,Command
Expand Down Expand Up @@ -251,28 +253,28 @@ try_failover_e164(State, ToDID) ->
%%------------------------------------------------------------------------------
-spec get_endpoint_data(ts_callflow:state()) -> {'endpoint', kz_json:object()}.
get_endpoint_data(State) ->
JObj = ts_callflow:get_request_data(State),
{ToUser, _} = kapps_util:get_destination(JObj, ?APP_NAME, <<"inbound_user_field">>),
RouteReq = ts_callflow:get_request_data(State),
{ToUser, _} = kapps_util:get_destination(RouteReq, ?APP_NAME, <<"inbound_user_field">>),
ToDID = knm_converters:normalize(ToUser),
case knm_number:lookup_account(ToDID) of
{'ok', AccountId, NumberProps} ->
get_endpoint_data(State, JObj, ToDID, AccountId, NumberProps);
get_endpoint_data(State, RouteReq, ToDID, AccountId, NumberProps);
_Else ->
lager:debug("unable to lookup account for number ~s: ~p", [ToDID, _Else]),
throw('unknown_account')
end.

-spec get_endpoint_data(ts_callflow:state(), kz_json:object(), kz_term:ne_binary(), kz_term:ne_binary(), knm_number_options:extra_options()) ->
-spec get_endpoint_data(ts_callflow:state(), kapi_route:req(), kz_term:ne_binary(), kz_term:ne_binary(), knm_number_options:extra_options()) ->
{'endpoint', kz_json:object()}.
get_endpoint_data(State, JObj, ToDID, AccountId, NumberProps) ->
get_endpoint_data(State, RouteReq, ToDID, AccountId, NumberProps) ->
ForceOut = knm_number_options:should_force_outbound(NumberProps),
lager:info("building endpoint for account id ~s with force out ~s", [AccountId, ForceOut]),
RoutingData1 = routing_data(ToDID, AccountId),

CidOptions = props:get_value(<<"Caller-ID-Options">>, RoutingData1),
CidFormat = kz_json:get_json_value(<<"format">>, CidOptions),
OldCNum = kz_json:get_ne_binary_value(<<"Caller-ID-Number">>, JObj),
OldCNam = kz_json:get_ne_binary_value(<<"Caller-ID-Name">>, JObj, OldCNum),
OldCNum = kz_json:get_ne_binary_value(<<"Caller-ID-Number">>, RouteReq),
OldCNam = kz_json:get_ne_binary_value(<<"Caller-ID-Name">>, RouteReq, OldCNum),
NewCallerId = maybe_anonymize_caller_id(State, {OldCNam, OldCNum}, CidFormat),
RoutingData = RoutingData1 ++ NewCallerId,

Expand Down Expand Up @@ -313,7 +315,10 @@ routing_data(ToDID, AccountId) ->
routing_data(ToDID, AccountId, Settings);
{'error', 'no_did_found'} ->
lager:info("DID ~s not found in ~s", [ToDID, AccountId]),
throw('no_did_found')
throw('no_did_found');
{'error', 'timeout'} ->
lager:error("timed out looking for DID ~s", [ToDID]),
throw('timeout')
end.

-spec routing_data(kz_term:ne_binary(), kz_term:ne_binary(), kz_json:object()) -> [{<<_:48,_:_*8>>, any()}].
Expand Down
42 changes: 21 additions & 21 deletions applications/trunkstore/src/ts_from_onnet.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

-define(SERVER, ?MODULE).

-spec start_link(kz_json:object()) -> kz_types:startlink_ret().
-spec start_link(kapi_route:req()) -> kz_types:startlink_ret().
start_link(RouteReqJObj) ->
proc_lib:start_link(?SERVER, 'init', [self(), RouteReqJObj]).

-spec init(pid(), kz_json:object()) -> 'ok'.
-spec init(pid(), kapi_route:req()) -> 'ok'.
init(Parent, RouteReqJObj) ->
proc_lib:init_ack(Parent, {'ok', self()}),
Funs = [fun maybe_referred_call/1
Expand All @@ -37,27 +37,27 @@ start_amqp(State) ->
maybe_onnet_data(ts_callflow:start_amqp(State)).

maybe_onnet_data(State) ->
JObj = ts_callflow:get_request_data(State),
RouteReq = ts_callflow:get_request_data(State),
CallID = ts_callflow:get_aleg_id(State),
AccountId = ts_callflow:get_account_id(State),
{ToUser, _} = kapps_util:get_destination(JObj, ?APP_NAME, <<"outbound_user_field">>),
{ToUser, _} = kapps_util:get_destination(RouteReq, ?APP_NAME, <<"outbound_user_field">>),
ToDID = knm_converters:normalize(ToUser, AccountId),
FromUser = kz_json:get_value(<<"Caller-ID-Name">>, JObj),
FromUser = kz_json:get_ne_binary_value(<<"Caller-ID-Name">>, RouteReq),

lager:info("on-net request from ~s(~s) to ~s", [FromUser, AccountId, ToDID]),
Options =
case ts_util:lookup_did(FromUser, AccountId) of
{'ok', Opts} -> Opts;
_ ->
Username = kz_json:get_value([<<"Custom-Channel-Vars">>, <<"Username">>], JObj, <<>>),
Realm = kz_json:get_value([<<"Custom-Channel-Vars">>, <<"Realm">>], JObj, <<>>),
Username = kz_json:get_value([<<"Custom-Channel-Vars">>, <<"Username">>], RouteReq, <<>>),
Realm = kz_json:get_value([<<"Custom-Channel-Vars">>, <<"Realm">>], RouteReq, <<>>),

case ts_util:lookup_user_flags(Username, Realm, AccountId) of
{'ok', Opts} -> Opts;
_ -> kz_json:new()
end
end,
ServerOptions = kz_json:get_value([<<"server">>, <<"options">>], Options, kz_json:new()),
ServerOptions = kz_json:get_json_value([<<"server">>, <<"options">>], Options, kz_json:new()),
case knm_converters:is_reconcilable(ToDID)
orelse knm_converters:classify(ToDID) =:= <<"emergency">>
orelse kz_json:is_true(<<"hunt_non_reconcilable">>, ServerOptions, 'false')
Expand Down Expand Up @@ -228,25 +228,25 @@ wait_for_bridge(State, CtlQ, Timeout) ->
{'error', #ts_callflow_state{aleg_callid='undefined'}} -> 'ok';
{'error', #ts_callflow_state{aleg_callid=CallId}=State1} ->
lager:info("responding to aleg ~s with 686", [CallId]),
kz_call_response:send(CallId, CtlQ, <<"686">>),
_ = kz_call_response:send(CallId, CtlQ, <<"686">>),
ts_callflow:send_hangup(State1, <<"686">>)
end.

-spec maybe_referred_call(kz_json:object()) -> kz_json:object().
maybe_referred_call(JObj) ->
maybe_fix_request(get_referred_by(JObj), JObj).
-spec maybe_referred_call(kapi_route:req()) -> kz_json:object().
maybe_referred_call(RouteReq) ->
maybe_fix_request(get_referred_by(RouteReq), RouteReq).

-spec maybe_redirected_call(kz_json:object()) -> kz_json:object().
maybe_redirected_call(JObj) ->
maybe_fix_request(get_redirected_by(JObj), JObj).
-spec maybe_redirected_call(kapi_route:req()) -> kz_json:object().
maybe_redirected_call(RouteReq) ->
maybe_fix_request(get_redirected_by(RouteReq), RouteReq).

-spec maybe_fix_request({binary(), binary()} | 'undefined', kz_json:object()) -> kz_json:object().
maybe_fix_request('undefined', JObj) -> JObj;
maybe_fix_request({Username, Realm}, JObj) ->
AccountId = kz_json:get_value([<<"Custom-Channel-Vars">>, <<"Account-ID">>], JObj),
-spec maybe_fix_request({binary(), binary()} | 'undefined', kapi_route:req()) -> kapi_route:req().
maybe_fix_request('undefined', RouteReq) -> RouteReq;
maybe_fix_request({Username, Realm}, RouteReq) ->
AccountId = kapi_route:account_id(RouteReq),
case ts_util:lookup_user_flags(Username, Realm, AccountId) of
{'ok', _Opts} -> kz_json:set_values(fix_request_values(Username, Realm), JObj);
_ -> JObj
{'ok', _Opts} -> kz_json:set_values(fix_request_values(Username, Realm), RouteReq);
_ -> RouteReq
end.

-spec fix_request_values(binary(), binary()) -> [{kz_json:path(), kz_term:ne_binary()}].
Expand Down
2 changes: 1 addition & 1 deletion applications/trunkstore/src/ts_offnet_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
start_link() ->
supervisor:start_link({'local', ?SERVER}, ?MODULE, []).

-spec start_handler(kz_term:ne_binary(), kz_json:object()) -> kz_types:sup_startchild_ret().
-spec start_handler(kz_term:ne_binary(), kapi_route:req()) -> kz_types:sup_startchild_ret().
start_handler(CallID, RouteReqJObj) ->
supervisor:start_child(?SERVER, ?WORKER_NAME_ARGS_TYPE(<<"offnet-", CallID/binary>>
,'ts_from_offnet'
Expand Down
2 changes: 1 addition & 1 deletion applications/trunkstore/src/ts_onnet_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
start_link() ->
supervisor:start_link({'local', ?SERVER}, ?MODULE, []).

-spec start_handler(kz_term:ne_binary(), kz_json:object()) -> kz_types:sup_startchild_ret().
-spec start_handler(kz_term:ne_binary(), kapi_route:req()) -> kz_types:sup_startchild_ret().
start_handler(CallID, RouteReqJObj) ->
supervisor:start_child(?SERVER, ?WORKER_NAME_ARGS_TYPE(<<"onnet-", CallID/binary>>
,'ts_from_onnet'
Expand Down
Loading

0 comments on commit 31b2a6c

Please sign in to comment.