Skip to content

Commit

Permalink
[4.3] PISTON-292: support for pause aliases (#6592)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfinke authored and jamesaimonetti committed Jun 23, 2020
1 parent 38ac480 commit dfa6cb3
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 34 deletions.
48 changes: 26 additions & 22 deletions applications/acdc/src/acdc_agent_fsm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
,originate_resp/2, originate_started/2, originate_uuid/2
,originate_failed/2
,sync_req/2, sync_resp/2
,pause/2
,pause/3
,resume/1
,end_wrapup/1

Expand Down Expand Up @@ -102,6 +102,7 @@

,sync_ref :: kz_term:api_reference()
,pause_ref :: kz_term:api_reference() | 'infinity'
,pause_alias :: kz_term:api_binary()

,member_call :: kapps_call:call() | 'undefined'
,member_call_id :: kz_term:api_binary()
Expand Down Expand Up @@ -269,9 +270,9 @@ sync_resp(ServerRef, JObj) ->
%% @doc
%% @end
%%------------------------------------------------------------------------------
-spec pause(kz_types:server_ref(), timeout()) -> 'ok'.
pause(ServerRef, Timeout) ->
gen_statem:cast(ServerRef, {'pause', Timeout}).
-spec pause(kz_types:server_ref(), timeout(), kz_term:api_binary()) -> 'ok'.
pause(ServerRef, Timeout, Alias) ->
gen_statem:cast(ServerRef, {'pause', Timeout, Alias}).

%%------------------------------------------------------------------------------
%% @doc
Expand Down Expand Up @@ -1363,26 +1364,26 @@ handle_event({'resume'}=Event, StateName, #state{agent_state_updates=Queue}=Stat
lager:debug("recv resume during ~p, delaying", [StateName]),
NewQueue = [Event | Queue],
{'next_state', StateName, State#state{agent_state_updates=NewQueue}};
handle_event({'pause', Timeout}, 'ringing', #state{agent_listener=AgentListener
,account_id=AccountId
,agent_id=AgentId
,member_call_id=CallId
,member_call_queue_id=QueueId
}=State) ->
handle_event({'pause', Timeout, Alias}, 'ringing', #state{agent_listener=AgentListener
,account_id=AccountId
,agent_id=AgentId
,member_call_id=CallId
,member_call_queue_id=QueueId
}=State) ->
%% Give up the current ringing call
acdc_agent_listener:hangup_call(AgentListener),
lager:debug("stopping ringing agent in order to move to pause"),
acdc_stats:call_missed(AccountId, QueueId, AgentId, CallId, <<"agent pausing">>),
NewFSMState = clear_call(State, 'failed'),
%% After clearing we are basically 'ready' state, pause from that state
handle_event({'pause', Timeout}, 'ready', NewFSMState);
handle_event({'pause', Timeout}=Event, 'ready', #state{agent_state_updates=Queue}=State) ->
lager:debug("recv status update: pausing for up to ~b s", [Timeout]),
handle_event({'pause', Timeout, Alias}, 'ready', NewFSMState);
handle_event({'pause', Timeout, _}=Event, 'ready', #state{agent_state_updates=Queue}=State) ->
lager:debug("recv status update: pausing for up to ~p s", [Timeout]),
NewQueue = [Event | Queue],
apply_state_updates(State#state{agent_state_updates=NewQueue});
handle_event({'pause', Timeout}, 'paused', State) ->
handle_event({'pause', Timeout}, 'ready', State);
handle_event({'pause', _}=Event, StateName, #state{agent_state_updates=Queue}=State) ->
handle_event({'pause', Timeout, Alias}, 'paused', State) ->
handle_event({'pause', Timeout, Alias}, 'ready', State);
handle_event({'pause', _, _}=Event, StateName, #state{agent_state_updates=Queue}=State) ->
lager:debug("recv pause during ~p, delaying", [StateName]),
NewQueue = [Event | Queue],
{'next_state', StateName, State#state{agent_state_updates=NewQueue}};
Expand Down Expand Up @@ -1963,6 +1964,7 @@ apply_state_updates_fold({_, StateName, #state{account_id=AccountId
,agent_listener=AgentListener
,wrapup_ref=WRef
,pause_ref=PRef
,pause_alias=Alias
}}=Acc, []) ->
lager:debug("resulting agent state ~s", [StateName]),
case StateName of
Expand All @@ -1972,11 +1974,11 @@ apply_state_updates_fold({_, StateName, #state{account_id=AccountId
'wrapup' -> acdc_agent_stats:agent_wrapup(AccountId, AgentId, time_left(WRef));
'paused' ->
acdc_agent_listener:send_agent_busy(AgentListener),
acdc_agent_stats:agent_paused(AccountId, AgentId, time_left(PRef))
acdc_agent_stats:agent_paused(AccountId, AgentId, time_left(PRef), Alias)
end,
Acc;
apply_state_updates_fold({_, _, State}, [{'pause', Timeout}|Updates]) ->
apply_state_updates_fold(handle_pause(Timeout, State), Updates);
apply_state_updates_fold({_, _, State}, [{'pause', Timeout, Alias}|Updates]) ->
apply_state_updates_fold(handle_pause(Timeout, Alias, State), Updates);
apply_state_updates_fold({_, _, State}, [{'resume'}|Updates]) ->
apply_state_updates_fold(handle_resume(State), Updates);
apply_state_updates_fold({_, 'wrapup', State}, [{'end_wrapup'}|Updates]) ->
Expand Down Expand Up @@ -2026,15 +2028,17 @@ handle_resume(#state{agent_listener=AgentListener
acdc_agent_listener:presence_update(AgentListener, ?PRESENCE_GREEN),
{'next_state', 'ready', State#state{pause_ref='undefined'}}.

-spec handle_pause(timeout(), state()) -> kz_types:handle_fsm_ret(state()).
handle_pause(Timeout, #state{agent_listener=AgentListener}=State) ->
-spec handle_pause(timeout(), kz_term:api_binary(), state()) -> kz_types:handle_fsm_ret(state()).
handle_pause(Timeout, Alias, #state{agent_listener=AgentListener}=State) ->
acdc_agent_listener:presence_update(AgentListener, ?PRESENCE_RED_FLASH),
State1 = case Timeout of
'infinity' ->
State#state{pause_ref='infinity'};
_ ->
Ref = start_pause_timer(Timeout),
State#state{pause_ref=Ref}
State#state{pause_ref=Ref
,pause_alias=Alias
}
end,
{'next_state', 'paused', State1}.

Expand Down
13 changes: 7 additions & 6 deletions applications/acdc/src/acdc_agent_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ handle_status_update(JObj, _Props) ->
<<"pause">> ->
'true' = kapi_acdc_agent:pause_v(JObj),
Timeout = kz_json:get_value(<<"Time-Limit">>, JObj, ?DEFAULT_PAUSE),
maybe_pause_agent(AccountId, AgentId, Timeout, JObj);
Alias = kz_json:get_value(<<"Alias">>, JObj),
maybe_pause_agent(AccountId, AgentId, Timeout, Alias, JObj);
<<"resume">> ->
'true' = kapi_acdc_agent:resume_v(JObj),
maybe_resume_agent(AccountId, AgentId, JObj);
Expand Down Expand Up @@ -165,16 +166,16 @@ maybe_stop_agent(AccountId, AgentId, JObj) ->

end.

maybe_pause_agent(AccountId, AgentId, <<"infinity">>, JObj) ->
maybe_pause_agent(AccountId, AgentId, 'infinity', JObj);
maybe_pause_agent(AccountId, AgentId, Timeout, JObj) ->
maybe_pause_agent(AccountId, AgentId, <<"infinity">>, Alias, JObj) ->
maybe_pause_agent(AccountId, AgentId, 'infinity', Alias, JObj);
maybe_pause_agent(AccountId, AgentId, Timeout, Alias, JObj) ->
case acdc_agents_sup:find_agent_supervisor(AccountId, AgentId) of
'undefined' -> lager:debug("agent ~s (~s) not found, nothing to do", [AgentId, AccountId]);
Sup when is_pid(Sup) ->
lager:debug("agent ~s(~s) is pausing for ~p", [AccountId, AgentId, Timeout]),
lager:debug("agent ~s(~s) is pausing (~p) for ~p", [AccountId, AgentId, Alias, Timeout]),
FSM = acdc_agent_sup:fsm(Sup),
acdc_agent_fsm:update_presence(FSM, presence_id(JObj), presence_state(JObj, 'undefined')),
acdc_agent_fsm:pause(FSM, Timeout)
acdc_agent_fsm:pause(FSM, Timeout, Alias)
end.

maybe_resume_agent(AccountId, AgentId, JObj) ->
Expand Down
14 changes: 10 additions & 4 deletions applications/acdc/src/acdc_agent_stats.erl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
,agent_connecting/3, agent_connecting/6
,agent_connected/3, agent_connected/6
,agent_wrapup/3
,agent_paused/3
,agent_paused/4
,agent_outbound/3

,handle_status_stat/2
Expand Down Expand Up @@ -167,16 +167,17 @@ agent_wrapup(AccountId, AgentId, WaitTime) ->
,fun kapi_acdc_stats:publish_status_wrapup/1
).

-spec agent_paused(kz_term:ne_binary(), kz_term:ne_binary(), timeout() | 'undefined') -> 'ok'.
agent_paused(AccountId, AgentId, 'undefined') ->
-spec agent_paused(kz_term:ne_binary(), kz_term:ne_binary(), timeout() | 'undefined', kz_term:api_binary()) -> 'ok'.
agent_paused(AccountId, AgentId, 'undefined', _) ->
lager:debug("undefined pause time for ~s(~s)", [AgentId, AccountId]);
agent_paused(AccountId, AgentId, PauseTime) ->
agent_paused(AccountId, AgentId, PauseTime, Alias) ->
Prop = props:filter_undefined(
[{<<"Account-ID">>, AccountId}
,{<<"Agent-ID">>, AgentId}
,{<<"Timestamp">>, kz_time:now_s()}
,{<<"Status">>, <<"paused">>}
,{<<"Pause-Time">>, PauseTime}
,{<<"Pause-Alias">>, Alias}
| kz_api:default_headers(?APP_NAME, ?APP_VERSION)
]),
log_status_change(AccountId, Prop),
Expand Down Expand Up @@ -228,6 +229,7 @@ handle_status_stat(JObj, Props) ->
,callid=kz_json:get_value(<<"Call-ID">>, JObj)
,wait_time=acdc_stats_util:wait_time(EventName, JObj)
,pause_time=acdc_stats_util:pause_time(EventName, JObj)
,pause_alias=kz_json:get_value(<<"Pause-Alias">>, JObj)
,caller_id_name=acdc_stats_util:caller_id_name(EventName, JObj)
,caller_id_number=acdc_stats_util:caller_id_number(EventName, JObj)
,queue_id=acdc_stats_util:queue_id(EventName, JObj)
Expand Down Expand Up @@ -421,6 +423,7 @@ status_stat_to_map(#status_stat{key=#status_stat_key{agent_id=AgentId
,status=Status
,wait_time=WT
,pause_time=PT
,pause_alias=Alias
,callid=CallId
,caller_id_name=CIDName
,caller_id_number=CIDNum
Expand All @@ -432,6 +435,7 @@ status_stat_to_map(#status_stat{key=#status_stat_key{agent_id=AgentId
,'status' => Status
,'wait_time' => WT
,'pause_time' => PT
,'pause_alias' => Alias
,'call_id' => CallId
,'caller_id_name' => CIDName
,'caller_id_number' => CIDNum
Expand All @@ -447,6 +451,7 @@ status_stat_to_doc(#status_stat{key=#status_stat_key{account_id=AccountId
,status=Status
,wait_time=WT
,pause_time=PT
,pause_alias=Alias
,callid=CallId
,caller_id_name=CIDName
,caller_id_number=CIDNum
Expand All @@ -459,6 +464,7 @@ status_stat_to_doc(#status_stat{key=#status_stat_key{account_id=AccountId
,{<<"status">>, Status}
,{<<"wait_time">>, WT}
,{<<"pause_time">>, PT}
,{<<"pause_alias">>, Alias}
,{<<"caller_id_name">>, CIDName}
,{<<"caller_id_number">>, CIDNum}
,{<<"queue_id">>, QueueId}
Expand Down
1 change: 1 addition & 0 deletions applications/acdc/src/acdc_stats.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@

,wait_time :: kz_term:api_integer() | '_'
,pause_time :: timeout() | 'undefined' | '_'
,pause_alias :: kz_term:api_binary() | '_'
,callid :: kz_term:api_binary() | '_'
,caller_id_name :: kz_term:api_binary() | '_'
,caller_id_number :: kz_term:api_binary() | '_'
Expand Down
1 change: 1 addition & 0 deletions applications/acdc/src/cb_agents.erl
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ publish_update(Context, AgentId, PubFun) ->
[{<<"Account-ID">>, cb_context:account_id(Context)}
,{<<"Agent-ID">>, AgentId}
,{<<"Time-Limit">>, cb_context:req_value(Context, <<"timeout">>)}
,{<<"Alias">>, cb_context:req_value(Context, <<"alias">>)}
,{<<"Presence-ID">>, cb_context:req_value(Context, <<"presence_id">>)}
,{<<"Presence-State">>, cb_context:req_value(Context, <<"presence_state">>)}
| kz_api:default_headers(?APP_NAME, ?APP_VERSION)
Expand Down
4 changes: 3 additions & 1 deletion applications/acdc/src/kapi_acdc_agent.erl
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ stats_resp_v(JObj) ->
]).
-define(AGENT_TYPES, []).

-define(OPTIONAL_PAUSE_HEADERS, [<<"Alias">>]).

-define(LOGIN_VALUES, [{<<"Event-Name">>, <<"login">>} | ?AGENT_VALUES]).
-define(LOGOUT_VALUES, [{<<"Event-Name">>, <<"logout">>} | ?AGENT_VALUES]).
-define(PAUSE_VALUES, [{<<"Event-Name">>, <<"pause">>} | ?AGENT_VALUES]).
Expand Down Expand Up @@ -315,7 +317,7 @@ logout_queue_v(JObj) ->
{'error', string()}.
pause(Props) when is_list(Props) ->
case pause_v(Props) of
'true' -> kz_api:build_message(Props, ?AGENT_HEADERS, ?OPTIONAL_AGENT_HEADERS);
'true' -> kz_api:build_message(Props, ?AGENT_HEADERS, ?OPTIONAL_AGENT_HEADERS ++ ?OPTIONAL_PAUSE_HEADERS);
'false' -> {'error', "Proplist failed validation for agent_pause"}
end;
pause(JObj) ->
Expand Down
2 changes: 1 addition & 1 deletion applications/acdc/src/kapi_acdc_stats.erl
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ status_resp_v(JObj) ->
status_resp_v(kz_json:to_proplist(JObj)).

-define(STATUS_HEADERS, [<<"Account-ID">>, <<"Agent-ID">>, <<"Timestamp">>]).
-define(STATUS_OPTIONAL_HEADERS, [<<"Wait-Time">>, <<"Pause-Time">>, <<"Call-ID">>
-define(STATUS_OPTIONAL_HEADERS, [<<"Wait-Time">>, <<"Pause-Time">>, <<"Pause-Alias">>, <<"Call-ID">>
,<<"Caller-ID-Name">>, <<"Caller-ID-Number">>
,<<"Queue-ID">>
]).
Expand Down

0 comments on commit dfa6cb3

Please sign in to comment.