Skip to content

Commit

Permalink
PISTON-1112: fix validation of agent pause timeout/time-limit (#6617)
Browse files Browse the repository at this point in the history
- schema validates system_config.acdc default_agent_pause_timeout for
  non-negative integers or the "infinity" special string
- refactored out ?DEFAULT_AGENT_PAUSE_TIMEOUT into shared header
- fixed acdc_maintenance expecting integer, despite possibility of
  <<"infinity">> value
- moved Time-Limit validation in kapi_acdc_agent into PAUSE_* macros
  rather than AGENT_*

PISTON-1119: add incorrectly gitignored kapi.acdc_agent schemas

- the rule *.log* in the root gitignore ignored these files :/
- remove Time-Limit from these schemas

PISTON-1122: Time-Limit should be optional in agent.pause AMQP events

- retain support for using default by omitting `"timeout"` from pause
  API reqs
  • Loading branch information
danielfinke authored and jamesaimonetti committed Sep 22, 2020
1 parent 02ec35e commit d1ae993
Show file tree
Hide file tree
Showing 15 changed files with 253 additions and 48 deletions.
4 changes: 4 additions & 0 deletions applications/acdc/include/acdc_config.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

-include_lib("kazoo_stdlib/include/kz_types.hrl").

-define(ACDC_CONFIG_CAT, <<"acdc">>).

-define(DEFAULT_AGENT_PAUSE_TIMEOUT, kapps_config:get(?ACDC_CONFIG_CAT, <<"default_agent_pause_timeout">>, 600)).

%% Save data to the DB
-define(ACDC_ARCHIVE_WINDOW,
kapps_config:get_integer(<<"acdc">>, <<"archive_window_s">>, ?SECONDS_IN_HOUR)).
Expand Down
4 changes: 1 addition & 3 deletions applications/acdc/src/acdc_agent_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
-include("acdc.hrl").
-include_lib("kazoo_amqp/include/kapi_conf.hrl").

-define(DEFAULT_PAUSE, kapps_config:get(?CONFIG_CAT, <<"default_agent_pause_timeout">>, 600)).

-spec handle_status_update(kz_json:object(), kz_term:proplist()) -> 'ok'.
handle_status_update(JObj, _Props) ->
_ = kz_util:put_callid(JObj),
Expand All @@ -43,7 +41,7 @@ handle_status_update(JObj, _Props) ->
maybe_stop_agent(AccountId, AgentId, JObj);
<<"pause">> ->
'true' = kapi_acdc_agent:pause_v(JObj),
Timeout = kz_json:get_value(<<"Time-Limit">>, JObj, ?DEFAULT_PAUSE),
Timeout = kz_json:get_value(<<"Time-Limit">>, JObj, ?DEFAULT_AGENT_PAUSE_TIMEOUT),
Alias = kz_json:get_value(<<"Alias">>, JObj),
maybe_pause_agent(AccountId, AgentId, Timeout, Alias, JObj);
<<"resume">> ->
Expand Down
7 changes: 3 additions & 4 deletions applications/acdc/src/acdc_maintenance.erl
Original file line number Diff line number Diff line change
Expand Up @@ -474,16 +474,15 @@ agent_logout(AcctId, AgentId) ->

-spec agent_pause(kz_term:ne_binary(), kz_term:ne_binary()) -> 'ok'.
agent_pause(AcctId, AgentId) ->
Timeout = kapps_config:get_integer(?CONFIG_CAT, <<"default_agent_pause_timeout">>, 600),
agent_pause(AcctId, AgentId, Timeout).
agent_pause(AcctId, AgentId, ?DEFAULT_AGENT_PAUSE_TIMEOUT).

-spec agent_pause(kz_term:ne_binary(), kz_term:ne_binary(), pos_integer()) -> 'ok'.
-spec agent_pause(kz_term:ne_binary(), kz_term:ne_binary(), pos_integer() | kz_term:ne_binary()) -> 'ok'.
agent_pause(AcctId, AgentId, Timeout) ->
kz_util:put_callid(?MODULE),
Update = props:filter_undefined(
[{<<"Account-ID">>, AcctId}
,{<<"Agent-ID">>, AgentId}
,{<<"Timeout">>, kz_term:to_integer(Timeout)}
,{<<"Time-Limit">>, Timeout}
| kz_api:default_headers(?APP_NAME, ?APP_VERSION)
]),
_ = kz_amqp_worker:cast(Update, fun kapi_acdc_agent:publish_pause/1),
Expand Down
8 changes: 3 additions & 5 deletions applications/acdc/src/cf_acdc_agent.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
,logout_agent/2
]).

-include("acdc_config.hrl").
-include_lib("callflow/src/callflow.hrl").

%%------------------------------------------------------------------------------
Expand Down Expand Up @@ -154,11 +155,8 @@ pause_agent(Call, AgentId, Data, Timeout) ->
_ = play_agent_pause(Call),
update_agent_status(Call, AgentId, Data, fun kapi_acdc_agent:publish_pause/1, Timeout).
pause_agent(Call, AgentId, Data) ->
Timeout = kz_json:get_value(<<"timeout">>
,Data
,kapps_config:get(<<"acdc">>, <<"default_agent_pause_timeout">>, 600)
),
lager:info("agent ~s is pausing work for ~b s", [AgentId, Timeout]),
Timeout = kz_json:get_value(<<"timeout">>, Data, ?DEFAULT_AGENT_PAUSE_TIMEOUT),
lager:info("agent ~s is pausing work for ~p s", [AgentId, Timeout]),
pause_agent(Call, AgentId, Data, Timeout).

resume_agent(Call, AgentId, Data) ->
Expand Down
16 changes: 12 additions & 4 deletions applications/acdc/src/kapi_acdc_agent.erl
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,15 @@ stats_resp_v(JObj) ->
-define(AGENT_KEY, "acdc.agent.action."). % append queue ID

-define(AGENT_HEADERS, [<<"Account-ID">>, <<"Agent-ID">>]).
-define(OPTIONAL_AGENT_HEADERS, [<<"Time-Limit">>, <<"Queue-ID">>
-define(OPTIONAL_AGENT_HEADERS, [<<"Queue-ID">>
,<<"Presence-ID">>, <<"Presence-State">>
]).
-define(AGENT_VALUES, [{<<"Event-Category">>, <<"agent">>}
,{<<"Presence-State">>, kapi_presence:presence_states()}
]).
-define(AGENT_TYPES, []).

-define(OPTIONAL_PAUSE_HEADERS, [<<"Alias">>]).
-define(OPTIONAL_PAUSE_HEADERS, [<<"Alias">>, <<"Time-Limit">> | ?OPTIONAL_AGENT_HEADERS]).

-define(LOGIN_VALUES, [{<<"Event-Name">>, <<"login">>} | ?AGENT_VALUES]).
-define(LOGOUT_VALUES, [{<<"Event-Name">>, <<"logout">>} | ?AGENT_VALUES]).
Expand All @@ -243,6 +243,14 @@ stats_resp_v(JObj) ->
-define(LOGOUT_QUEUE_VALUES, [{<<"Event-Name">>, <<"logout_queue">>} | ?AGENT_VALUES]).
-define(RESTART_VALUES, [{<<"Event-Name">>, <<"restart">>} | ?AGENT_VALUES]).

-define(PAUSE_TYPES, [{<<"Time-Limit">>, fun(<<"infinity">>) -> 'true';
(TimeLimit) when is_integer(TimeLimit) -> TimeLimit >= 0;
(_) -> 'false'
end
}
| ?AGENT_TYPES
]).

-spec login(kz_term:api_terms()) ->
{'ok', iolist()} |
{'error', string()}.
Expand Down Expand Up @@ -317,15 +325,15 @@ 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 ++ ?OPTIONAL_PAUSE_HEADERS);
'true' -> kz_api:build_message(Props, ?AGENT_HEADERS, ?OPTIONAL_PAUSE_HEADERS);
'false' -> {'error', "Proplist failed validation for agent_pause"}
end;
pause(JObj) ->
pause(kz_json:to_proplist(JObj)).

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

Expand Down
28 changes: 6 additions & 22 deletions applications/crossbar/priv/api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -6681,9 +6681,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -6729,9 +6726,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -6777,9 +6771,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -6853,9 +6844,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -6901,9 +6889,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -7057,9 +7042,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -7105,9 +7087,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down Expand Up @@ -29446,7 +29425,12 @@
"default_agent_pause_timeout": {
"default": 600,
"description": "acdc default agent pause timeout",
"type": "integer"
"minimum": 0,
"pattern": "infinity",
"type": [
"integer",
"string"
]
},
"max_connect_failures": {
"default": 3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@
},
"Queue-ID": {
"type": "string"
},
"Time-Limit": {
"type": "integer"
}
},
"required": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"_id": "kapi.acdc_agent.login",
"description": "AMQP API for acdc_agent.login",
"properties": {
"Account-ID": {
"type": "string"
},
"Agent-ID": {
"type": "string"
},
"Event-Category": {
"enum": [
"agent"
],
"type": "string"
},
"Event-Name": {
"enum": [
"login"
],
"type": "string"
},
"Presence-ID": {
"type": "string"
},
"Presence-State": {
"enum": [
"trying",
"online",
"offline",
"early",
"confirmed",
"terminated"
],
"type": "string"
},
"Queue-ID": {
"type": "string"
}
},
"required": [
"Account-ID",
"Agent-ID"
],
"type": "object"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"_id": "kapi.acdc_agent.login_queue",
"description": "AMQP API for acdc_agent.login_queue",
"properties": {
"Account-ID": {
"type": "string"
},
"Agent-ID": {
"type": "string"
},
"Event-Category": {
"enum": [
"agent"
],
"type": "string"
},
"Event-Name": {
"enum": [
"login_queue"
],
"type": "string"
},
"Presence-ID": {
"type": "string"
},
"Presence-State": {
"enum": [
"trying",
"online",
"offline",
"early",
"confirmed",
"terminated"
],
"type": "string"
},
"Queue-ID": {
"type": "string"
}
},
"required": [
"Account-ID",
"Agent-ID"
],
"type": "object"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"_id": "kapi.acdc_agent.login_resp",
"description": "AMQP API for acdc_agent.login_resp",
"properties": {
"Event-Category": {
"enum": [
"agent"
],
"type": "string"
},
"Event-Name": {
"enum": [
"login_resp"
],
"type": "string"
},
"Status": {
"enum": [
"success",
"failed"
],
"type": "string"
}
},
"required": [
"Status"
],
"type": "object"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"_id": "kapi.acdc_agent.logout",
"description": "AMQP API for acdc_agent.logout",
"properties": {
"Account-ID": {
"type": "string"
},
"Agent-ID": {
"type": "string"
},
"Event-Category": {
"enum": [
"agent"
],
"type": "string"
},
"Event-Name": {
"enum": [
"logout"
],
"type": "string"
},
"Presence-ID": {
"type": "string"
},
"Presence-State": {
"enum": [
"trying",
"online",
"offline",
"early",
"confirmed",
"terminated"
],
"type": "string"
},
"Queue-ID": {
"type": "string"
}
},
"required": [
"Account-ID",
"Agent-ID"
],
"type": "object"
}
Loading

0 comments on commit d1ae993

Please sign in to comment.