Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.3] KCON-1: search for conference focus before origination #6545

Merged
merged 2 commits into from
May 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion applications/crossbar/doc/conference.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,27 @@ Dial-able endpoints are

Note: Phone numbers will involve some internal legs being generated (loopback legs) to process the number as if it was a call coming in for the desired number. This means billing and limits will be applied just the same as if a user dialed the number from their device.

**Examples**
#### Dial schema

Schema for conference dial API command



Key | Description | Type | Default | Required | Support Level
--- | ----------- | ---- | ------- | -------- | -------------
`caller_id_name` | Caller ID Name to use when dialing out to endpoints | `string()` | | `false` |
`caller_id_number` | Caller ID Number to use when dialing out to endpoints | `string()` | | `false` |
`endpoints.[]` | | `string()|[#/definitions/devices](#devices)` | | |
`endpoints` | Endpoints to dial out to and join to the conference | `array()` | | `true` |
`participant_flags.[]` | | `string('mute' | 'deaf' | 'distribute_dtmf' | 'is_moderator' | 'disable_moh' | 'ghost' | 'join_existing' | 'video_mute')` | | `false` |
`participant_flags` | Participant flags applied to each endpoint when it joins the conference | `array(string('mute' | 'deaf' | 'distribute_dtmf' | 'is_moderator' | 'disable_moh' | 'ghost' | 'join_existing' | 'video_mute'))` | | `false` |
`profile_name` | The profile name to use for configuration | `string()` | | `false` |
`target_call_id` | Existing UUID to use as a hint for where to start the conference | `string()` | | `false` |
`timeout` | How long to try to reach the endpoint(s) | `integer()` | | `false` |



#### Example payloads

```json
{
Expand Down
3 changes: 3 additions & 0 deletions applications/crossbar/priv/api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -11702,6 +11702,9 @@
},
"UUID": {
"type": "string"
},
"Zone": {
"type": "string"
}
},
"required": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
},
"UUID": {
"type": "string"
},
"Zone": {
"type": "string"
}
},
"required": [
Expand Down
32 changes: 22 additions & 10 deletions applications/crossbar/src/modules/cb_conferences.erl
Original file line number Diff line number Diff line change
Expand Up @@ -483,16 +483,16 @@ exec_dial_endpoints(Context, ConferenceId, Data, ToDial) ->
,{<<"Conference-ID">>, ConferenceId}
,{<<"Custom-Application-Vars">>, CAVs}
,{<<"Endpoints">>, ToDial}
,{<<"Participant-Flags">>, kz_json:get_list_value(<<"participant_flags">>, Data)}
,{<<"Profile-Name">>, kz_json:get_ne_binary_value(<<"profile_name">>, Data)}
,{<<"Msg-ID">>, cb_context:req_id(Context)}
,{<<"Outbound-Call-ID">>, kz_json:get_ne_binary_value(<<"outbound_call_id">>, Data)}
,{<<"Participant-Flags">>, kz_json:get_list_value(<<"participant_flags">>, Data)}
,{<<"Profile-Name">>, kz_json:get_ne_binary_value(<<"profile_name">>, Data)}
,{<<"Target-Call-ID">>, TargetCallId}
,{<<"Timeout">>, Timeout}
| kz_api:default_headers(?APP_NAME, ?APP_VERSION)
],

Zone = zone(TargetCallId),
Zone = zone(ConferenceId, TargetCallId),
case kz_amqp_worker:call(Command
,fun(P) -> kapi_conference:publish_dial(Zone, P) end
,fun kapi_conference:dial_resp_v/1
Expand All @@ -512,10 +512,10 @@ exec_dial_endpoints(Context, ConferenceId, Data, ToDial) ->
])
end.

-spec zone(kz_term:api_ne_binary()) -> kz_term:ne_binary().
zone('undefined') ->
kz_config:zone('binary');
zone(TargetCallId) ->
-spec zone(kz_term:ne_binary(), kz_term:api_ne_binary()) -> kz_term:ne_binary().
zone(ConferenceId, 'undefined') ->
discover_conference_zone(ConferenceId);
zone(ConferenceId, TargetCallId) ->
Req = [{<<"Call-ID">>, TargetCallId}
,{<<"Fields">>, <<"all">>}
,{<<"Active-Only">>, 'true'}
Expand All @@ -533,10 +533,22 @@ zone(TargetCallId) ->
lager:info("got back channel resp, using target ~s zone ~s", [TargetCallId, Zone]),
Zone;
_E ->
lager:info("target ~s not found (~p), using local zone: ~p"
,[TargetCallId, _E, kz_config:zone('binary')]
lager:info("target ~s not found (~p), checking conference id ~s"
,[TargetCallId, _E, ConferenceId]
),
kz_config:zone('binary')
discover_conference_zone(ConferenceId)
end.

-spec discover_conference_zone(kz_term:ne_binary()) -> kz_term:ne_binary().
discover_conference_zone(ConferenceId) ->
case kapps_conference_command:search(ConferenceId, ?APP_NAME, ?APP_VERSION) of
{'error', _E} ->
lager:debug("failed to search for ~s: ~p", [ConferenceId, _E]),
kz_config:zone('binary');
{'ok', SearchResp} ->
Zone = kz_json:get_ne_binary_value(<<"Zone">>, SearchResp, kz_config:zone('binary')),
lager:debug("found conference ~s in zone ~s", [ConferenceId, Zone]),
Zone
end.

-record(build_acc, {endpoints = [] :: kz_json:objects()
Expand Down
3 changes: 2 additions & 1 deletion applications/ecallmgr/src/ecallmgr_fs_conferences.erl
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ handle_search_conference(JObj, _Props, Name) ->
,{<<"Switch-External-IP">>, ExternalIP}
,{<<"Participant-Count">>, length(Participants)}
,{<<"Participants">>, participants_to_json(Participants)}
,{<<"Zone">>, kz_config:zone('binary')}
| kz_api:default_headers(?APP_NAME, ?APP_VERSION)
],
kapi_conference:publish_search_resp(kz_api:server_id(JObj), Resp);
Expand Down Expand Up @@ -467,7 +468,7 @@ conference_control_node(Node, Props, undefined) ->
UUID = kzd_freeswitch:call_id(Props),
CtrlNode = kz_nodes:whapp_oldest_node(ecallmgr),
ToSet = [{<<"Ecallmgr-Node">>, kz_term:to_binary(CtrlNode)}],
ecallmgr_fs_command:bg_set(Node, UUID, ToSet),
_ = ecallmgr_fs_command:bg_set(Node, UUID, ToSet),
CtrlNode;
conference_control_node(_Node, _Props, Value) ->
Value.
Expand Down
1 change: 1 addition & 0 deletions core/kazoo_amqp/src/api/kapi_conference.erl
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
,<<"Switch-Hostname">>
,<<"Switch-URL">>
,<<"UUID">>
,<<"Zone">>
]).
-define(SEARCH_RESP_VALUES, [{<<"Event-Category">>, <<"conference">>}
,{<<"Event-Name">>, <<"search_resp">>}
Expand Down
10 changes: 9 additions & 1 deletion core/kazoo_call/src/kapps_conference_command.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

-include("kapps_call_command.hrl").

-export([search/1]).
-export([search/1, search/3]).
-export([deaf_participant/2]).
-export([participant_energy/3]).
-export([kick/1, kick/2]).
Expand All @@ -33,10 +33,18 @@
-spec search(kapps_conference:conference()) ->
{'ok', kz_json:object()} |
{'error', any()}.

search(Conference) ->
AppName = kapps_conference:application_name(Conference),
AppVersion = kapps_conference:application_version(Conference),
ConferenceId = kapps_conference:id(Conference),

search(ConferenceId, AppName, AppVersion).

-spec search(kz_term:ne_binary(), kz_term:ne_binary(), kz_term:ne_binary()) ->
{'ok', kz_json:object()} |
{'error', any()}.
search(ConferenceId, AppName, AppVersion) ->
Req = [{<<"Conference-ID">>, ConferenceId}
| kz_api:default_headers(AppName, AppVersion)
],
Expand Down
10 changes: 5 additions & 5 deletions scripts/validate_mkdocs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
from __future__ import print_function
#!/usr/bin/env python3

import yaml, os.path, sys
from functools import reduce

# from https://stackoverflow.com/questions/5574702/how-to-print-to-stderr-in-python
def eprint(*args, **kwargs):
Expand All @@ -25,7 +25,7 @@ def parse_page_string(errors_detected, page):
def parse_page(errors_detected, page):
"parse a page for existence"
if isinstance(page, dict):
return reduce(parse_page_dict, page.items(), errors_detected)
return reduce(parse_page_dict, list(page.items()), errors_detected)
elif isinstance(page, list):
return reduce(parse_page, page, errors_detected)
elif isinstance(page, str):
Expand All @@ -34,11 +34,11 @@ def parse_page(errors_detected, page):
return errors_detected

stream = open("doc/mkdocs/mkdocs.yml", 'r')
mkdocs = yaml.load_all(stream)
mkdocs = yaml.safe_load_all(stream)
errors_detected = False

for doc in mkdocs:
for k,v in doc.items():
for k,v in list(doc.items()):
if "pages" == k:
errors_detected = parse_page(False, v)

Expand Down