Skip to content

Commit

Permalink
PISTON-522: add end_wrapup kapi to cancel agent wrapup early (2600hz#…
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfinke authored and lazedo committed Jan 29, 2018
1 parent 4f293c7 commit 7eb2b04
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 2 deletions.
24 changes: 24 additions & 0 deletions applications/acdc/src/acdc_agent_fsm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
,sync_req/2, sync_resp/2
,pause/2
,resume/1
,end_wrapup/1

,add_acdc_queue/2, rm_acdc_queue/2
,update_presence/3
Expand Down Expand Up @@ -267,6 +268,14 @@ pause(ServerRef, Timeout) ->
resume(ServerRef) ->
gen_statem:cast(ServerRef, {'resume'}).

%%--------------------------------------------------------------------
%% @doc
%% @end
%%--------------------------------------------------------------------
-spec end_wrapup(kz_types:server_ref()) -> 'ok'.
end_wrapup(ServerRef) ->
gen_statem:cast(ServerRef, {'end_wrapup'}).

%%--------------------------------------------------------------------
%% @doc
%% Request the agent listener bind to queue and conditionally send an
Expand Down Expand Up @@ -1366,6 +1375,11 @@ handle_event({'pause', _}=Event, StateName, #state{agent_state_updates=Queue}=St
lager:debug("recv pause during ~p, delaying", [StateName]),
NewQueue = [Event | Queue],
{'next_state', StateName, State#state{agent_state_updates=NewQueue}};
handle_event({'end_wrapup'}=Event, 'wrapup', #state{agent_state_updates=Queue}=State) ->
NewQueue = [Event | Queue],
apply_state_updates(State#state{agent_state_updates=NewQueue});
handle_event({'end_wrapup'}, StateName, State) ->
{'next_state', StateName, State};
handle_event({'add_acdc_queue', QueueId}, StateName, #state{agent_listener=AgentListener}=State) ->
acdc_agent_listener:add_acdc_queue(AgentListener, QueueId, StateName),
{'next_state', StateName, State};
Expand Down Expand Up @@ -1927,6 +1941,10 @@ apply_state_updates_fold({_, _, State}, [{'pause', Timeout}|Updates]) ->
apply_state_updates_fold(handle_pause(Timeout, 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]) ->
apply_state_updates_fold(handle_end_wrapup('ready', State), Updates);
apply_state_updates_fold({_, StateName, State}, [{'end_wrapup'}|Updates]) ->
apply_state_updates_fold(handle_end_wrapup(StateName, State), Updates);
apply_state_updates_fold({_, _, State}, [{'agent_logout'}|_]) ->
lager:debug("agent logging out"),
%% Do not continue fold, stop statem
Expand Down Expand Up @@ -1976,3 +1994,9 @@ handle_pause(Timeout, #state{agent_listener=AgentListener}=State) ->
Ref = start_pause_timer(Timeout),
State1 = State#state{pause_ref=Ref},
{'next_state', 'paused', State1}.

-spec handle_end_wrapup(atom(), state()) -> kz_types:handle_fsm_ret(state()).
handle_end_wrapup(NextState, #state{wrapup_ref=Ref}=State) ->
lager:debug("end_wrapup received, cancelling wrapup timers"),
maybe_stop_timer(Ref),
{'next_state', NextState, State#state{wrapup_ref='undefined'}}.
14 changes: 14 additions & 0 deletions applications/acdc/src/acdc_agent_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ handle_status_update(JObj, _Props) ->
<<"resume">> ->
'true' = kapi_acdc_agent:resume_v(JObj),
maybe_resume_agent(AccountId, AgentId, JObj);
<<"end_wrapup">> ->
'true' = kapi_acdc_agent:end_wrapup_v(JObj),
maybe_end_wrapup_agent(AccountId, AgentId, JObj);
Event -> maybe_agent_queue_change(AccountId, AgentId, Event
,kz_json:get_value(<<"Queue-ID">>, JObj)
,JObj
Expand Down Expand Up @@ -180,6 +183,17 @@ maybe_resume_agent(AccountId, AgentId, JObj) ->
acdc_agent_fsm:resume(FSM)
end.

-spec maybe_end_wrapup_agent(kz_term:ne_binary(), kz_term:ne_binary(), kz_json:object()) -> 'ok'.
maybe_end_wrapup_agent(AccountId, AgentId, 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 ending wrapup: ~p", [AccountId, AgentId, Sup]),
FSM = acdc_agent_sup:fsm(Sup),
acdc_agent_fsm:update_presence(FSM, presence_id(JObj), presence_state(JObj, 'undefined')),
acdc_agent_fsm:end_wrapup(FSM)
end.

-spec handle_sync_req(kz_json:object(), kz_term:proplist()) -> 'ok'.
handle_sync_req(JObj, Props) ->
'true' = kapi_acdc_agent:sync_req_v(JObj),
Expand Down
1 change: 1 addition & 0 deletions applications/acdc/src/acdc_agent_manager.erl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
,{<<"agent">>, <<"logout">>}
,{<<"agent">>, <<"pause">>}
,{<<"agent">>, <<"resume">>}
,{<<"agent">>, <<"end_wrapup">>}
,{<<"agent">>, <<"login_queue">>}
,{<<"agent">>, <<"logout_queue">>}
]
Expand Down
5 changes: 3 additions & 2 deletions applications/acdc/src/cb_agents.erl
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ post(Context, AgentId, ?STATUS_PATH_TOKEN) ->
<<"login">> -> publish_update(Context, AgentId, fun kapi_acdc_agent:publish_login/1);
<<"logout">> -> publish_update(Context, AgentId, fun kapi_acdc_agent:publish_logout/1);
<<"pause">> -> publish_update(Context, AgentId, fun kapi_acdc_agent:publish_pause/1);
<<"resume">> -> publish_update(Context, AgentId, fun kapi_acdc_agent:publish_resume/1)
<<"resume">> -> publish_update(Context, AgentId, fun kapi_acdc_agent:publish_resume/1);
<<"end_wrapup">> -> publish_update(Context, AgentId, fun kapi_acdc_agent:publish_end_wrapup/1)
end,
crossbar_util:response(<<"status update sent">>, Context);
post(Context, AgentId, ?QUEUE_STATUS_PATH_TOKEN) ->
Expand Down Expand Up @@ -576,7 +577,7 @@ validate_status_change(Context) ->
check_for_status_error(Context, cb_context:req_value(Context, <<"status">>))
end.

-define(STATUS_CHANGES, [<<"login">>, <<"logout">>, <<"pause">>, <<"resume">>]).
-define(STATUS_CHANGES, [<<"login">>, <<"logout">>, <<"pause">>, <<"resume">>, <<"end_wrapup">>]).
-spec validate_status_change(cb_context:context(), kz_term:api_binary()) ->
cb_context:context().
validate_status_change(Context, S) ->
Expand Down
27 changes: 27 additions & 0 deletions applications/acdc/src/kapi_acdc_agent.erl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
,logout/1, logout_v/1
,pause/1, pause_v/1
,resume/1, resume_v/1
,end_wrapup/1, end_wrapup_v/1
,login_queue/1, login_queue_v/1
,logout_queue/1, logout_queue_v/1

Expand All @@ -37,6 +38,7 @@
,publish_logout/1, publish_logout/2
,publish_pause/1, publish_pause/2
,publish_resume/1, publish_resume/2
,publish_end_wrapup/1, publish_end_wrapup/2
,publish_login_queue/1, publish_login_queue/2
,publish_logout_queue/1, publish_logout_queue/2

Expand Down Expand Up @@ -226,6 +228,7 @@ stats_resp_v(JObj) ->
-define(LOGOUT_VALUES, [{<<"Event-Name">>, <<"logout">>} | ?AGENT_VALUES]).
-define(PAUSE_VALUES, [{<<"Event-Name">>, <<"pause">>} | ?AGENT_VALUES]).
-define(RESUME_VALUES, [{<<"Event-Name">>, <<"resume">>} | ?AGENT_VALUES]).
-define(END_WRAPUP_VALUES, [{<<"Event-Name">>, <<"end_wrapup">>} | ?AGENT_VALUES]).
-define(LOGIN_QUEUE_VALUES, [{<<"Event-Name">>, <<"login_queue">>} | ?AGENT_VALUES]).
-define(LOGOUT_QUEUE_VALUES, [{<<"Event-Name">>, <<"logout_queue">>} | ?AGENT_VALUES]).

Expand Down Expand Up @@ -330,6 +333,21 @@ resume_v(Prop) when is_list(Prop) ->
kz_api:validate(Prop, ?AGENT_HEADERS, ?RESUME_VALUES, ?AGENT_TYPES);
resume_v(JObj) -> resume_v(kz_json:to_proplist(JObj)).

-spec end_wrapup(kz_term:api_terms()) ->
{'ok', iolist()} |
{'error', string()}.
end_wrapup(Props) when is_list(Props) ->
case end_wrapup_v(Props) of
'true' -> kz_api:build_message(Props, ?AGENT_HEADERS, ?OPTIONAL_AGENT_HEADERS);
'false' -> {'error', "Proplist failed validation for agent_end_wrapup"}
end;
end_wrapup(JObj) -> end_wrapup(kz_json:to_proplist(JObj)).

-spec end_wrapup_v(kz_term:api_terms()) -> boolean().
end_wrapup_v(Prop) when is_list(Prop) ->
kz_api:validate(Prop, ?AGENT_HEADERS, ?END_WRAPUP_VALUES, ?AGENT_TYPES);
end_wrapup_v(JObj) -> end_wrapup_v(kz_json:to_proplist(JObj)).

-spec agent_status_routing_key(kz_term:proplist()) -> kz_term:ne_binary().
agent_status_routing_key(Props) when is_list(Props) ->
Id = props:get_value(<<"Agent-ID">>, Props, <<"*">>),
Expand Down Expand Up @@ -530,6 +548,15 @@ publish_resume(API, ContentType) ->
{'ok', Payload} = resume((API1 = kz_api:prepare_api_payload(API, ?RESUME_VALUES))),
amqp_util:kapps_publish(agent_status_routing_key(API1), Payload, ContentType).

-spec publish_end_wrapup(kz_term:api_terms()) -> 'ok'.
publish_end_wrapup(JObj) ->
publish_end_wrapup(JObj, ?DEFAULT_CONTENT_TYPE).

-spec publish_end_wrapup(kz_term:api_terms(), kz_term:ne_binary()) -> 'ok'.
publish_end_wrapup(API, ContentType) ->
{'ok', Payload} = end_wrapup((API1 = kz_api:prepare_api_payload(API, ?END_WRAPUP_VALUES))),
amqp_util:kapps_publish(agent_status_routing_key(API1), Payload, ContentType).

-spec publish_login_resp(kz_term:ne_binary(), kz_term:api_terms()) -> 'ok'.
publish_login_resp(RespQ, JObj) ->
publish_login_resp(RespQ, JObj, ?DEFAULT_CONTENT_TYPE).
Expand Down
48 changes: 48 additions & 0 deletions applications/crossbar/priv/api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -5171,6 +5171,54 @@
}
}
},
"kapi.acdc_agent.end_wrapup": {
"description": "AMQP API for acdc_agent.end_wrapup",
"properties": {
"Account-ID": {
"type": "string"
},
"Agent-ID": {
"type": "string"
},
"Event-Category": {
"enum": [
"agent"
],
"type": "string"
},
"Event-Name": {
"enum": [
"end_wrapup"
],
"type": "string"
},
"Presence-ID": {
"type": "string"
},
"Presence-State": {
"enum": [
"trying",
"online",
"offline",
"early",
"confirmed",
"terminated"
],
"type": "string"
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
"Account-ID",
"Agent-ID"
],
"type": "object"
},
"kapi.acdc_agent.login": {
"description": "AMQP API for acdc_agent.login",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"_id": "kapi.acdc_agent.end_wrapup",
"description": "AMQP API for acdc_agent.end_wrapup",
"properties": {
"Account-ID": {
"type": "string"
},
"Agent-ID": {
"type": "string"
},
"Event-Category": {
"enum": [
"agent"
],
"type": "string"
},
"Event-Name": {
"enum": [
"end_wrapup"
],
"type": "string"
},
"Presence-ID": {
"type": "string"
},
"Presence-State": {
"enum": [
"trying",
"online",
"offline",
"early",
"confirmed",
"terminated"
],
"type": "string"
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
"Account-ID",
"Agent-ID"
],
"type": "object"
}

0 comments on commit 7eb2b04

Please sign in to comment.