Skip to content

Commit

Permalink
Merge pull request 2600hz#1 from 2600hz/master
Browse files Browse the repository at this point in the history
Update OpenTelecom to latest commits from 2600Hz
  • Loading branch information
kjcsb1 authored Jan 9, 2017
2 parents 6e85c96 + 1fc5e39 commit e9299c7
Show file tree
Hide file tree
Showing 1,332 changed files with 12,492 additions and 5,445 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ FMT = $(ROOT)/make/erlang-formatter-master/fmt.sh

KAZOODIRS = core/Makefile applications/Makefile

.PHONY: $(KAZOODIRS) deps core apps xref xref_release dialyze dialyze-it dialyze-apps dialyze-core dialyze-kazoo clean clean-test clean-release build-release build-ci-release tar-release release read-release-cookie elvis install ci diff fmt bump-copyright apis validate-swagger coverage-report fs-headers
.PHONY: $(KAZOODIRS) deps core apps xref xref_release dialyze dialyze-it dialyze-apps dialyze-core dialyze-kazoo clean clean-test clean-release build-release build-ci-release tar-release release read-release-cookie elvis install ci diff fmt bump-copyright apis validate-swagger coverage-report fs-headers docs

all: compile rel/dev-vm.args

Expand Down Expand Up @@ -120,7 +120,7 @@ read-release-cookie:
DIALYZER ?= dialyzer
PLT ?= .kazoo.plt

OTP_APPS ?= erts kernel stdlib crypto public_key ssl asn1 inets
OTP_APPS ?= erts kernel stdlib crypto public_key ssl asn1 inets xmerl
$(PLT): DEPS_SRCS ?= $(shell find $(ROOT)/deps -name src )
# $(PLT): CORE_EBINS ?= $(shell find $(ROOT)/core -name ebin)
$(PLT):
Expand Down Expand Up @@ -189,10 +189,14 @@ apis:
@ERL_LIBS=deps/:core/:applications/ $(ROOT)/scripts/generate-schemas.escript
@$(ROOT)/scripts/format-json.sh applications/crossbar/priv/couchdb/schemas/*.json
@ERL_LIBS=deps/:core/:applications/ $(ROOT)/scripts/generate-api-endpoints.escript
@$(ROOT)/scripts/generate-doc-schemas.sh applications/crossbar/doc/ref/*.md
@$(ROOT)/scripts/format-json.sh applications/crossbar/priv/api/swagger.json
@$(ROOT)/scripts/format-json.sh applications/crossbar/priv/api/*.json
@ERL_LIBS=deps/:core/:applications/ $(ROOT)/scripts/generate-fs-headers-hrl.escript

docs:
$(ROOT)/scripts/validate_mkdocs.py

fs-headers:
@ERL_LIBS=deps/:core/:applications/ $(ROOT)/scripts/generate-fs-headers-hrl.escript

Expand Down
4 changes: 4 additions & 0 deletions applications/acdc/src/acdc.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@

-type deliveries() :: [gen_listener:basic_deliver()].

-type fsm_state_name() :: 'wait' | 'sync' | 'ready' | 'ringing' |
'ringing_callback' | 'awaiting_callback' |
'answered' | 'wrapup' | 'paused' | 'outbound'.

%% Check for cleanup every 5 minutes
-define(CLEANUP_PERIOD, kapps_config:get_integer(?CONFIG_CAT, <<"cleanup_period_ms">>, 360000)).

Expand Down
33 changes: 31 additions & 2 deletions applications/acdc/src/acdc_agent_fsm.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2012-2016, 2600Hz
%%% @copyright (C) 2012-2017, 2600Hz
%%% @doc
%%% Tracks the agent's state, responds to messages from the corresponding
%%% acdc_agent gen_listener process.
Expand All @@ -23,6 +23,8 @@
,sync_req/2, sync_resp/2
,pause/2
,resume/1

,add_acdc_queue/2, rm_acdc_queue/2
,update_presence/3
,agent_logout/1
,refresh/2
Expand Down Expand Up @@ -275,6 +277,26 @@ pause(FSM, Timeout) ->
resume(FSM) ->
gen_fsm:send_all_state_event(FSM, {'resume'}).

%%--------------------------------------------------------------------
%% @doc
%% Request the agent listener bind to queue and conditionally send an
%% availability update depending on agent state
%% @end
%%--------------------------------------------------------------------
-spec add_acdc_queue(server_ref(), ne_binary()) -> 'ok'.
add_acdc_queue(FSM, QueueId) ->
gen_fsm:send_all_state_event(FSM, {'add_acdc_queue', QueueId}).

%%--------------------------------------------------------------------
%% @doc
%% Request the agent listener unbind from queue and send an
%% unavailability update
%% @end
%%--------------------------------------------------------------------
-spec rm_acdc_queue(server_ref(), ne_binary()) -> 'ok'.
rm_acdc_queue(FSM, QueueId) ->
gen_fsm:send_all_state_event(FSM, {'rm_acdc_queue', QueueId}).

%%--------------------------------------------------------------------
%% @doc
%% @end
Expand Down Expand Up @@ -1340,14 +1362,20 @@ 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({'add_acdc_queue', QueueId}, StateName, #state{agent_listener=AgentListener}=State) ->
acdc_agent_listener:add_acdc_queue(AgentListener, QueueId, StateName),
{'next_state', StateName, State};
handle_event({'rm_acdc_queue', QueueId}, StateName, #state{agent_listener=AgentListener}=State) ->
acdc_agent_listener:rm_acdc_queue(AgentListener, QueueId),
{'next_state', StateName, State};
handle_event({'update_presence', PresenceId, PresenceState}, 'ready', State) ->
handle_presence_update(PresenceId, PresenceState, State),
{'next_state', 'ready', State};
handle_event({'update_presence', _, _}=Event, StateName, #state{agent_state_updates=Queue}=State) ->
NewQueue = [Event | Queue],
{'next_state', StateName, State#state{agent_state_updates=NewQueue}};
handle_event({'refresh', AgentJObj}, StateName, #state{agent_listener=AgentListener}=State) ->
acdc_agent_listener:refresh_config(AgentListener, kz_json:get_value(<<"queues">>, AgentJObj)),
acdc_agent_listener:refresh_config(AgentListener, kz_json:get_value(<<"queues">>, AgentJObj), StateName),
{'next_state', StateName, State};
handle_event('load_endpoints', StateName, #state{agent_listener='undefined'}=State) ->
lager:debug("agent proc not ready, not loading endpoints yet"),
Expand Down Expand Up @@ -1919,6 +1947,7 @@ apply_state_updates_fold({_, StateName, #state{account_id=AccountId
acdc_agent_stats:agent_ready(AccountId, AgentId);
'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))
end,
Acc;
Expand Down
6 changes: 3 additions & 3 deletions applications/acdc/src/acdc_agent_handler.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2012-2016, 2600Hz INC
%%% @copyright (C) 2012-2017, 2600Hz INC
%%% @doc
%%% Handlers for various call events, acdc events, etc
%%% @end
Expand Down Expand Up @@ -70,15 +70,15 @@ maybe_agent_queue_change(AccountId, AgentId, <<"login_queue">>, QueueId, JObj) -
lager:debug("queue login for agent ~s into ~s", [AgentId, QueueId]),
case maybe_start_agent(AccountId, AgentId, JObj) of
'fail' -> lager:error("could not start agent process for ~s", [AgentId]);
Sup -> acdc_agent_listener:add_acdc_queue(acdc_agent_sup:listener(Sup), QueueId)
Sup -> acdc_agent_fsm:add_acdc_queue(acdc_agent_sup:fsm(Sup), QueueId)
end;
maybe_agent_queue_change(AccountId, AgentId, <<"logout_queue">>, QueueId, JObj) ->
lager:debug("queue logout for agent ~s into ~s", [AgentId, QueueId]),
case acdc_agents_sup:find_agent_supervisor(AccountId, AgentId) of
'undefined' -> lager:debug("agent process for ~s already stopped");
Sup ->
maybe_update_presence(Sup, JObj),
acdc_agent_listener:rm_acdc_queue(acdc_agent_sup:listener(Sup), QueueId)
acdc_agent_fsm:rm_acdc_queue(acdc_agent_sup:fsm(Sup), QueueId)
end.

-spec maybe_start_agent(ne_binary(), ne_binary(), kz_json:object()) -> pid() | 'fail'.
Expand Down
81 changes: 60 additions & 21 deletions applications/acdc/src/acdc_agent_listener.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2012-2016, 2600Hz INC
%%% @copyright (C) 2012-2017, 2600Hz INC
%%% @doc
%%%
%%% @end
Expand All @@ -26,11 +26,12 @@
,originate_uuid/3
,outbound_call/2
,send_agent_available/1
,send_agent_busy/1
,send_sync_req/1
,send_sync_resp/3, send_sync_resp/4
,config/1, refresh_config/2
,config/1, refresh_config/3
,send_status_resume/1
,add_acdc_queue/2
,add_acdc_queue/3
,rm_acdc_queue/2
,call_status_req/1, call_status_req/2
,stop/1
Expand Down Expand Up @@ -262,6 +263,10 @@ outbound_call(Srv, CallId) ->
send_agent_available(Srv) ->
gen_listener:cast(Srv, 'send_agent_available').

-spec send_agent_busy(pid()) -> 'ok'.
send_agent_busy(Srv) ->
gen_listener:cast(Srv, 'send_agent_busy').

-spec send_sync_req(pid()) -> 'ok'.
send_sync_req(Srv) -> gen_listener:cast(Srv, {'send_sync_req'}).

Expand All @@ -274,9 +279,10 @@ send_sync_resp(Srv, Status, ReqJObj, Options) ->
-spec config(pid()) -> config().
config(Srv) -> gen_listener:call(Srv, 'config').

-spec refresh_config(pid(), api_ne_binaries()) -> 'ok'.
refresh_config(_, 'undefined') -> 'ok';
refresh_config(Srv, Qs) -> gen_listener:cast(Srv, {'refresh_config', Qs}).
-spec refresh_config(pid(), api_ne_binaries(), fsm_state_name()) -> 'ok'.
refresh_config(_, 'undefined', _) -> 'ok';
refresh_config(Srv, Qs, StateName) ->
gen_listener:cast(Srv, {'refresh_config', Qs, StateName}).

-spec agent_info(pid(), kz_json:path()) -> kz_json:api_json_term().
agent_info(Srv, Field) -> gen_listener:call(Srv, {'agent_info', Field}).
Expand All @@ -285,9 +291,9 @@ agent_info(Srv, Field) -> gen_listener:call(Srv, {'agent_info', Field}).
send_status_resume(Srv) ->
gen_listener:cast(Srv, {'send_status_update', 'resume'}).

-spec add_acdc_queue(pid(), ne_binary()) -> 'ok'.
add_acdc_queue(Srv, Q) ->
gen_listener:cast(Srv, {'add_acdc_queue', Q}).
-spec add_acdc_queue(pid(), ne_binary(), fsm_state_name()) -> 'ok'.
add_acdc_queue(Srv, Q, StateName) ->
gen_listener:cast(Srv, {'add_acdc_queue', Q, StateName}).

-spec rm_acdc_queue(pid(), ne_binary()) -> 'ok'.
rm_acdc_queue(Srv, Q) ->
Expand Down Expand Up @@ -433,11 +439,11 @@ handle_call(_Request, _From, #state{}=State) ->
%% @end
%%--------------------------------------------------------------------
-spec handle_cast(any(), state()) -> handle_cast_ret_state(state()).
handle_cast({'refresh_config', Qs}, #state{agent_queues=Queues}=State) ->
handle_cast({'refresh_config', Qs, StateName}, #state{agent_queues=Queues}=State) ->
{Add, Rm} = acdc_agent_util:changed(Queues, Qs),

Self = self(),
_ = [gen_listener:cast(Self, {'add_acdc_queue', A}) || A <- Add],
_ = [gen_listener:cast(Self, {'add_acdc_queue', A, StateName}) || A <- Add],
_ = [gen_listener:cast(Self, {'rm_acdc_queue', R}) || R <- Rm],
{'noreply', State};
handle_cast({'stop_agent', Req}, #state{supervisor=Supervisor}=State) ->
Expand All @@ -455,16 +461,16 @@ handle_cast({'fsm_started', FSMPid}, State) ->
handle_cast({'gen_listener', {'created_queue', Q}}, State) ->
{'noreply', State#state{my_q=Q}, 'hibernate'};

handle_cast({'add_acdc_queue', Q}, #state{agent_queues=Qs
,acct_id=AcctId
,agent_id=AgentId
}=State) when is_binary(Q) ->
handle_cast({'add_acdc_queue', Q, StateName}, #state{agent_queues=Qs
,acct_id=AcctId
,agent_id=AgentId
}=State) when is_binary(Q) ->
case lists:member(Q, Qs) of
'true' ->
lager:debug("queue ~s already added", [Q]),
{'noreply', State};
'false' ->
add_queue_binding(AcctId, AgentId, Q),
add_queue_binding(AcctId, AgentId, Q, StateName),
{'noreply', State#state{agent_queues=[Q|Qs]}}
end;

Expand Down Expand Up @@ -494,7 +500,7 @@ handle_cast('bind_to_member_reqs', #state{agent_queues=Qs
,acct_id=AcctId
,agent_id=AgentId
}=State) ->
_ = [add_queue_binding(AcctId, AgentId, Q) || Q <- Qs],
_ = [add_queue_binding(AcctId, AgentId, Q, 'ready') || Q <- Qs],
{'noreply', State};

handle_cast({'rebind_events', OldCallId, NewCallId}, State) ->
Expand Down Expand Up @@ -667,6 +673,7 @@ handle_cast({'member_connect_accepted'}, #state{msg_queue_id=AmqpQueue
,call=Call
,acct_id=AcctId
,agent_id=AgentId
,agent_queues=Qs
,my_id=MyId
,record_calls=ShouldRecord
,recording_url=RecordingUrl
Expand All @@ -675,12 +682,14 @@ handle_cast({'member_connect_accepted'}, #state{msg_queue_id=AmqpQueue
maybe_start_recording(Call, ShouldRecord, RecordingUrl),

send_member_connect_accepted(AmqpQueue, call_id(Call), AcctId, AgentId, MyId),
[send_agent_busy(AcctId, AgentId, QueueId) || QueueId <- Qs],
{'noreply', State};

handle_cast({'member_connect_accepted', ACallId}, #state{msg_queue_id=AmqpQueue
,call=Call
,acct_id=AcctId
,agent_id=AgentId
,agent_queues=Qs
,my_id=MyId
,record_calls=ShouldRecord
,recording_url=RecordingUrl
Expand All @@ -694,6 +703,7 @@ handle_cast({'member_connect_accepted', ACallId}, #state{msg_queue_id=AmqpQueue
lager:debug("new agent call ids: ~p", [ACallIds1]),

send_member_connect_accepted(AmqpQueue, call_id(Call), AcctId, AgentId, MyId),
[send_agent_busy(AcctId, AgentId, QueueId) || QueueId <- Qs],
{'noreply', State#state{agent_call_ids=ACallIds1}, 'hibernate'};

handle_cast({'member_connect_resp', ReqJObj}, #state{agent_id=AgentId
Expand Down Expand Up @@ -763,9 +773,13 @@ handle_cast({'originate_uuid', UUID, CtlQ}, #state{agent_call_ids=ACallIds}=Stat
lager:debug("updating ~s with ~s in ~p", [UUID, CtlQ, ACallIds]),
{'noreply', State#state{agent_call_ids=[{UUID, CtlQ} | props:delete(UUID, ACallIds)]}};

handle_cast({'outbound_call', CallId}, State) ->
handle_cast({'outbound_call', CallId}, #state{agent_id=AgentId
,acct_id=AcctId
,agent_queues=Qs
}=State) ->
_ = kz_util:put_callid(CallId),
acdc_util:bind_to_call_events(CallId),
[send_agent_busy(AcctId, AgentId, QueueId) || QueueId <- Qs],

lager:debug("bound to agent's outbound call ~s", [CallId]),
{'noreply', State#state{call=kapps_call:set_call_id(CallId, kapps_call:new())}, 'hibernate'};
Expand All @@ -777,6 +791,13 @@ handle_cast('send_agent_available', #state{agent_id=AgentId
[send_agent_available(AcctId, AgentId, QueueId) || QueueId <- Qs],
{'noreply', State};

handle_cast('send_agent_busy', #state{agent_id=AgentId
,acct_id=AcctId
,agent_queues=Qs
}=State) ->
[send_agent_busy(AcctId, AgentId, QueueId) || QueueId <- Qs],
{'noreply', State};

handle_cast({'send_sync_req'}, #state{my_id=MyId
,my_q=MyQ
,acct_id=AcctId
Expand Down Expand Up @@ -1127,16 +1148,17 @@ outbound_call_id(CallId, AgentId) when is_binary(CallId) ->
outbound_call_id(Call, AgentId) ->
outbound_call_id(kapps_call:call_id(Call), AgentId).

-spec add_queue_binding(ne_binary(), ne_binary(), ne_binary()) -> 'ok'.
add_queue_binding(AcctId, AgentId, QueueId) ->
-spec add_queue_binding(ne_binary(), ne_binary(), ne_binary(), fsm_state_name()) ->
'ok'.
add_queue_binding(AcctId, AgentId, QueueId, StateName) ->
lager:debug("adding queue binding for ~s", [QueueId]),
gen_listener:add_binding(self()
,'acdc_queue'
,[{'restrict_to', ['member_connect_req']}
,{'queue_id', QueueId}
,{'account_id', AcctId}
]),
send_agent_available(AcctId, AgentId, QueueId).
send_availability_update(AcctId, AgentId, QueueId, StateName).

-spec rm_queue_binding(ne_binary(), ne_binary(), ne_binary()) -> 'ok'.
rm_queue_binding(AcctId, AgentId, QueueId) ->
Expand All @@ -1149,6 +1171,13 @@ rm_queue_binding(AcctId, AgentId, QueueId) ->
]),
send_agent_unavailable(AcctId, AgentId, QueueId).

-spec send_availability_update(ne_binary(), ne_binary(), ne_binary(), fsm_state_name()) ->
'ok'.
send_availability_update(AcctId, AgentId, QueueId, 'ready') ->
send_agent_available(AcctId, AgentId, QueueId);
send_availability_update(AcctId, AgentId, QueueId, _) ->
send_agent_busy(AcctId, AgentId, QueueId).

-spec send_agent_available(ne_binary(), ne_binary(), ne_binary()) -> 'ok'.
send_agent_available(AcctId, AgentId, QueueId) ->
Prop = [{<<"Account-ID">>, AcctId}
Expand All @@ -1159,6 +1188,16 @@ send_agent_available(AcctId, AgentId, QueueId) ->
],
kapi_acdc_queue:publish_agent_change(Prop).

-spec send_agent_busy(ne_binary(), ne_binary(), ne_binary()) -> 'ok'.
send_agent_busy(AcctId, AgentId, QueueId) ->
Prop = [{<<"Account-ID">>, AcctId}
,{<<"Agent-ID">>, AgentId}
,{<<"Queue-ID">>, QueueId}
,{<<"Change">>, <<"busy">>}
| kz_api:default_headers(?APP_NAME, ?APP_VERSION)
],
kapi_acdc_queue:publish_agent_change(Prop).

-spec send_agent_unavailable(ne_binary(), ne_binary(), ne_binary()) -> 'ok'.
send_agent_unavailable(AcctId, AgentId, QueueId) ->
Prop = [{<<"Account-ID">>, AcctId}
Expand Down
2 changes: 1 addition & 1 deletion applications/acdc/src/acdc_agent_maintenance.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2013-2016, 2600Hz
%%% @copyright (C) 2013-2017, 2600Hz
%%% @doc
%%%
%%% @end
Expand Down
2 changes: 1 addition & 1 deletion applications/acdc/src/acdc_agent_manager.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2012-2016, 2600Hz
%%% @copyright (C) 2012-2017, 2600Hz
%%% @doc
%%% Manages agent processes:
%%% starting when an agent logs in
Expand Down
2 changes: 1 addition & 1 deletion applications/acdc/src/acdc_agent_stats.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2014-2016, 2600Hz
%%% @copyright (C) 2014-2017, 2600Hz
%%% @doc
%%% Collector of stats for agents
%%% @end
Expand Down
2 changes: 1 addition & 1 deletion applications/acdc/src/acdc_agent_sup.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2012-2016, 2600Hz INC
%%% @copyright (C) 2012-2017, 2600Hz INC
%%% @doc
%%%
%%% @end
Expand Down
2 changes: 1 addition & 1 deletion applications/acdc/src/acdc_agent_util.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2013-2016, 2600Hz
%%% @copyright (C) 2013-2017, 2600Hz
%%% @doc
%%%
%%% @end
Expand Down
Loading

0 comments on commit e9299c7

Please sign in to comment.