Skip to content

Instantly share code, notes, and snippets.

@pc-m
Last active April 5, 2023 12:57
Show Gist options
  • Select an option

  • Save pc-m/74a2b9d76f7ccd7aeaa480189fd0e937 to your computer and use it in GitHub Desktop.

Select an option

Save pc-m/74a2b9d76f7ccd7aeaa480189fd0e937 to your computer and use it in GitHub Desktop.
diff --git a/wazo_calld/controller.py b/wazo_calld/controller.py
index 276283ac..d7900c03 100644
--- a/wazo_calld/controller.py
+++ b/wazo_calld/controller.py
@@ -20,6 +20,8 @@ from .bus import CoreBusConsumer, CoreBusPublisher
from .collectd import CollectdPublisher
from .http_server import api, HTTPServer
from .service_discovery import self_check
+from .helpers.channel_proxy import ChannelProxy
+
logger = logging.getLogger(__name__)
@@ -49,6 +51,7 @@ class Controller:
]
self._pubsub = pubsub.Pubsub()
+ self._channel_proxy = ChannelProxy(self.ari.client)
plugin_helpers.load(
namespace='wazo_calld.plugins',
names=config['enabled_plugins'],
@@ -58,6 +61,7 @@ class Controller:
'asyncio': self.asyncio,
'bus_publisher': self.bus_publisher,
'bus_consumer': self.bus_consumer,
+ 'channel_proxy': self._channel_proxy,
'collectd': self.collectd,
'config': config,
'status_aggregator': self.status_aggregator,
@@ -73,7 +77,7 @@ class Controller:
)
def run(self):
- logger.info('wazo-calld starting...')
+ logger.info('wazo-calld starting... with channel constant patch')
self.token_renewer.subscribe_to_token_change(
self.token_status.token_change_callback
)
@@ -89,7 +93,7 @@ class Controller:
with ServiceCatalogRegistration(*self._service_registration_params):
self.http_server.run()
finally:
- logger.info('wazo-calld stopping...')
+ logger.info('wazo-calld stopping... with channel constant patch')
self._pubsub.publish('stopping', None)
self.asyncio.stop()
self.ari.stop()
diff --git a/wazo_calld/helpers/__init__.py b/wazo_calld/helpers/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/wazo_calld/helpers/channel_proxy.py b/wazo_calld/helpers/channel_proxy.py
new file mode 100644
index 00000000..1e7546da
--- /dev/null
+++ b/wazo_calld/helpers/channel_proxy.py
@@ -0,0 +1,80 @@
+# Copyright 2023 The Wazo Authors (see the AUTHORS file)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import logging
+
+from time import time
+
+logger = logging.getLogger(__name__)
+
+CHANNEL_CACHE_EXPIRATION = 60 * 60
+
+
+class ChannelProxy:
+ def __init__(self, ari):
+ self._ari = ari
+ self._channel_variable_cache = {}
+ self._channel_json_cache = {}
+ self._last_cache_cleanup = time()
+
+ def get_variable(self, channel_id, name):
+ response = self._ari.channels.getChannelVar(channelId=channel_id, variable=name)
+ return response['value']
+
+ def get_constant(self, channel_id, name):
+ try:
+ result = self._get_cached_value(channel_id, name)
+ except KeyError:
+ result = self.get_variable(channel_id, name)
+ self._insert_value(channel_id, name, result)
+ return result
+
+ def get_constant_json(self, channel_id):
+ try:
+ result = self._channel_json_cache[channel_id]
+ except KeyError:
+ channel = self._ari.channels.get(channelId=channel_id)
+ result = channel.json
+ self._channel_json_cache[channel_id] = result
+ return result
+
+ def on_hang_up(self, channel, event):
+ self._remove_cached_channel(channel.id)
+ self._remove_old_calls_from_cache()
+
+ def _remove_old_calls_from_cache(self):
+ # To avoid leaking channel variables if an event ever gets missed
+ # we are going to clean the cache every once in a while
+ now = time()
+ threshold = now - CHANNEL_CACHE_EXPIRATION
+ if self._last_cache_cleanup > threshold:
+ return
+
+ to_remove = set()
+ for call_id in self._channel_variable_cache.keys():
+ if float(call_id) < threshold:
+ to_remove.add(call_id)
+
+ for call_id in self._channel_json_cache.keys():
+ if float(call_id) < threshold:
+ to_remove.add(call_id)
+
+ logger.debug('Removing %s calls from the cache', len(to_remove))
+ for call_id in to_remove:
+ self._remove_cached_channel(call_id)
+
+ self._last_cache_cleanup = now
+
+ def _remove_cached_channel(self, channel_id):
+ logger.debug('removing %s from channel proxy', channel_id)
+ self._channel_variable_cache.pop(channel_id, None)
+ self._channel_json_cache.pop(channel_id, None)
+
+ def _insert_value(self, channel_id, name, value):
+ if channel_id not in self._channel_variable_cache:
+ self._channel_variable_cache[channel_id] = {name: value}
+ else:
+ self._channel_variable_cache[channel_id][name] = value
+
+ def _get_cached_value(self, channel_id, name):
+ return self._channel_variable_cache[channel_id][name]
diff --git a/wazo_calld/plugin_helpers/ari_.py b/wazo_calld/plugin_helpers/ari_.py
index 59ad5ec3..0ecef980 100644
--- a/wazo_calld/plugin_helpers/ari_.py
+++ b/wazo_calld/plugin_helpers/ari_.py
@@ -145,20 +145,21 @@ class GlobalVariableConstantNameAdapter:
class Channel:
- def __init__(self, channel_id, ari):
+ def __init__(self, channel_id, ari, channel_proxy):
self.id = channel_id
self._ari = ari
+ self._channel_proxy = channel_proxy
def __str__(self):
return self.id
def asterisk_name(self):
try:
- channel = self._ari.channels.get(channelId=self.id)
+ json = self._channel_proxy.get_constant_json(self.id)
except ARINotFound:
return False
- return channel.json['name']
+ return json['name']
def connected_channels(self):
channel_ids = set(
@@ -175,11 +176,14 @@ class Channel:
channel_ids.remove(self.id)
except KeyError:
pass
- return {Channel(channel_id, self._ari) for channel_id in channel_ids}
+ return {
+ Channel(channel_id, self._ari, self._channel_proxy)
+ for channel_id in channel_ids
+ }
def conversation_id(self):
try:
- linkedid = self._get_var('CHANNEL(linkedid)')
+ linkedid = self._get_constant('CHANNEL(linkedid)')
except ARINotFound:
return None
return linkedid
@@ -192,25 +196,25 @@ class Channel:
channel_id = connected_channels.pop().id
except KeyError:
raise NotEnoughChannels()
- return Channel(channel_id, self._ari)
+ return Channel(channel_id, self._ari, self._channel_proxy)
def user(self, default=None):
if self.is_local():
try:
- uuid = self._get_var('WAZO_DEREFERENCED_USERUUID')
+ uuid = self._get_constant('WAZO_DEREFERENCED_USERUUID')
except ARINotFound:
return default
return uuid
try:
- uuid = self._get_var('XIVO_USERUUID')
+ uuid = self._get_constant('XIVO_USERUUID')
return uuid
except ARINotFound:
return default
def tenant_uuid(self, default=None):
try:
- tenant_uuid = self._get_var('WAZO_TENANT_UUID')
+ tenant_uuid = self._get_constant('WAZO_TENANT_UUID')
except ARINotFound:
return default
return tenant_uuid
@@ -224,11 +228,11 @@ class Channel:
def is_local(self):
try:
- channel = self._ari.channels.get(channelId=self.id)
+ json = self._channel_proxy.get_constant_json(self.id)
except ARINotFound:
return False
- return channel.json['name'].startswith('Local/')
+ return json['name'].startswith('Local/')
def is_caller(self):
try:
@@ -238,7 +242,7 @@ class Channel:
pass
try:
- direction = self._get_var('WAZO_CHANNEL_DIRECTION')
+ direction = self._get_constant('WAZO_CHANNEL_DIRECTION')
return direction == 'to-wazo'
except ARINotFound:
pass
@@ -256,15 +260,13 @@ class Channel:
def is_sip(self):
try:
- return self._get_var('CHANNEL(channeltype)') == 'PJSIP'
+ return self._get_constant('CHANNEL(channeltype)') == 'PJSIP'
except ARINotFound:
return False
def dialed_extension(self):
try:
- return self._ari.channels.getChannelVar(
- channelId=self.id, variable='WAZO_ENTRY_EXTEN'
- )['value']
+ return self._channel_proxy.get_constant(self.id, 'WAZO_ENTRY_EXTEN')
except ARINotFound:
try:
channel = self._ari.channels.get(channelId=self.id)
@@ -301,13 +303,13 @@ class Channel:
def sip_call_id_unsafe(self):
'''This method expects a SIP channel'''
try:
- return self._get_var('CHANNEL(pjsip,call-id)')
+ return self._get_constant('CHANNEL(pjsip,call-id)')
except ARINotFound:
return
def line_id(self):
try:
- return int(self._get_var('WAZO_LINE_ID'))
+ return int(self._get_constant('WAZO_LINE_ID'))
except ARINotFound:
return
except ValueError:
@@ -345,16 +347,18 @@ class Channel:
except ARINotFound:
return
+ def _get_constant(self, var):
+ return self._channel_proxy.get_constant(self.id, var)
+
def _get_var(self, var):
- return self._ari.channels.getChannelVar(channelId=self.id, variable=var)[
- 'value'
- ]
+ return self._channel_proxy.get_variable(self.id, var)
class Bridge:
- def __init__(self, bridge_id, ari):
+ def __init__(self, bridge_id, ari, channel_proxy):
self.id = bridge_id
self._ari = ari
+ self._channel_proxy = channel_proxy
self.global_variables = GlobalVariableNameDecorator(
GlobalVariableAdapter(self._ari),
'WAZO_BRIDGE_{bridge_id}_VARIABLE_{{}}'.format(bridge_id=self.id),
@@ -395,7 +399,7 @@ class Bridge:
return set()
return set(
- Channel(channel_id, self._ari).user()
+ Channel(channel_id, self._ari, self._channel_proxy).user()
for channel_id in bridge.json['channels']
)
@@ -408,12 +412,13 @@ class Bridge:
class BridgeSnapshot(Bridge):
- def __init__(self, snapshot, ari):
+ def __init__(self, snapshot, ari, channel_proxy):
self._snapshot = snapshot
- super().__init__(snapshot['id'], ari)
+ self._channel_proxy = channel_proxy
+ super().__init__(snapshot['id'], ari, channel_proxy)
def valid_user_uuids(self):
return set(
- Channel(channel_id, self._ari).user()
+ Channel(channel_id, self._ari, self._channel_proxy).user()
for channel_id in self._snapshot['channels']
)
diff --git a/wazo_calld/plugin_helpers/tests/test_ari_helpers.py b/wazo_calld/plugin_helpers/tests/test_ari_helpers.py
index 634fc489..03948581 100644
--- a/wazo_calld/plugin_helpers/tests/test_ari_helpers.py
+++ b/wazo_calld/plugin_helpers/tests/test_ari_helpers.py
@@ -13,12 +13,14 @@ from hamcrest import (
from ari.exceptions import ARINotFound
+from wazo_calld.helpers.channel_proxy import ChannelProxy
from ..ari_ import Channel
class TestChannelHelper(TestCase):
def setUp(self):
self.ari = Mock()
+ self.channel_proxy = ChannelProxy(self.ari)
def test_dialed_extension_when_no_channel_exist(self):
self.ari.channels.getChannelVar.side_effect = ARINotFound(
@@ -30,7 +32,7 @@ class TestChannelHelper(TestCase):
ari_client=self.ari,
)
- channel = Channel(s.channel_id, self.ari)
+ channel = Channel(s.channel_id, self.ari, self.channel_proxy)
result = channel.dialed_extension()
assert_that(result, equal_to(None))
@@ -40,7 +42,7 @@ class TestChannelHelper(TestCase):
mocked_channel = self.ari.channels.get.return_value = Mock()
mocked_channel.json = {'dialplan': {'exten': 's'}}
- channel = Channel(s.channel_id, self.ari)
+ channel = Channel(s.channel_id, self.ari, self.channel_proxy)
result = channel.dialed_extension()
assert_that(result, equal_to(s.exten))
@@ -53,7 +55,7 @@ class TestChannelHelper(TestCase):
self.ari.channels.get.return_value = mocked_channel = Mock()
mocked_channel.json = {'dialplan': {'exten': s.exten}}
- channel = Channel(s.channel_id, self.ari)
+ channel = Channel(s.channel_id, self.ari, self.channel_proxy)
result = channel.dialed_extension()
assert_that(result, equal_to(s.exten))
diff --git a/wazo_calld/plugins/adhoc_conferences/plugin.py b/wazo_calld/plugins/adhoc_conferences/plugin.py
index 11bd03cc..0fbdac5b 100644
--- a/wazo_calld/plugins/adhoc_conferences/plugin.py
+++ b/wazo_calld/plugins/adhoc_conferences/plugin.py
@@ -20,6 +20,7 @@ class Plugin:
ari = dependencies['ari']
bus_publisher = dependencies['bus_publisher']
config = dependencies['config']
+ channel_proxy = dependencies['channel_proxy']
token_changed_subscribe = dependencies['token_changed_subscribe']
amid_client = AmidClient(**config['amid'])
@@ -28,11 +29,14 @@ class Plugin:
notifier = AdhocConferencesNotifier(bus_publisher)
adhoc_conferences_service = AdhocConferencesService(
- amid_client, ari.client, notifier
+ amid_client,
+ ari.client,
+ notifier,
+ channel_proxy,
)
startup_callback_collector = CallbackCollector()
- adhoc_conferences_stasis = AdhocConferencesStasis(ari, notifier)
+ adhoc_conferences_stasis = AdhocConferencesStasis(ari, notifier, channel_proxy)
ari.client_initialized_subscribe(startup_callback_collector.new_source())
startup_callback_collector.subscribe(adhoc_conferences_stasis.initialize)
diff --git a/wazo_calld/plugins/adhoc_conferences/services.py b/wazo_calld/plugins/adhoc_conferences/services.py
index 38bae499..4b2bac6c 100644
--- a/wazo_calld/plugins/adhoc_conferences/services.py
+++ b/wazo_calld/plugins/adhoc_conferences/services.py
@@ -24,10 +24,11 @@ logger = logging.getLogger(__name__)
class AdhocConferencesService:
- def __init__(self, amid_client, ari, notifier):
+ def __init__(self, amid_client, ari, notifier, channel_proxy):
self._amid_client = amid_client
self._ari = ari
self._notifier = notifier
+ self._channel_proxy = channel_proxy
def create_from_user(self, host_call_id, participant_call_ids, user_uuid):
logger.debug(
@@ -36,7 +37,7 @@ class AdhocConferencesService:
host_call_id,
participant_call_ids,
)
- host_channel = Channel(host_call_id, self._ari)
+ host_channel = Channel(host_call_id, self._ari, self._channel_proxy)
if not host_channel.exists():
raise HostCallNotFound(host_call_id)
@@ -54,7 +55,9 @@ class AdhocConferencesService:
raise HostCallAlreadyInConference(host_call_id)
for participant_call_id in participant_call_ids:
- if not Channel(participant_call_id, self._ari).exists():
+ if not Channel(
+ participant_call_id, self._ari, self._channel_proxy
+ ).exists():
raise ParticipantCallNotFound(participant_call_id)
try:
@@ -116,7 +119,7 @@ class AdhocConferencesService:
}
def _find_peer_channel(self, call_id):
- return Channel(call_id, self._ari).only_connected_channel()
+ return Channel(call_id, self._ari, self._channel_proxy).only_connected_channel()
def _redirect_host(self, host_call_id, host_peer_channel_id, adhoc_conference_id):
try:
@@ -215,7 +218,7 @@ class AdhocConferencesService:
)
def delete_from_user(self, adhoc_conference_id, user_uuid):
- bridge_helper = Bridge(adhoc_conference_id, self._ari)
+ bridge_helper = Bridge(adhoc_conference_id, self._ari, self._channel_proxy)
if not bridge_helper.exists():
raise AdhocConferenceNotFound(adhoc_conference_id)
@@ -230,11 +233,11 @@ class AdhocConferencesService:
def add_participant_from_user(
self, adhoc_conference_id, participant_call_id, user_uuid
):
- bridge_helper = Bridge(adhoc_conference_id, self._ari)
+ bridge_helper = Bridge(adhoc_conference_id, self._ari, self._channel_proxy)
if not bridge_helper.exists():
raise AdhocConferenceNotFound(adhoc_conference_id)
- if not Channel(participant_call_id, self._ari).exists():
+ if not Channel(participant_call_id, self._ari, self._channel_proxy).exists():
raise ParticipantCallNotFound(participant_call_id)
if (
@@ -277,7 +280,7 @@ class AdhocConferencesService:
def remove_participant_from_user(
self, adhoc_conference_id, participant_call_id, user_uuid
):
- bridge_helper = Bridge(adhoc_conference_id, self._ari)
+ bridge_helper = Bridge(adhoc_conference_id, self._ari, self._channel_proxy)
if not bridge_helper.exists():
raise AdhocConferenceNotFound(adhoc_conference_id)
@@ -287,7 +290,7 @@ class AdhocConferencesService:
):
raise AdhocConferenceNotFound(adhoc_conference_id)
- if not Channel(participant_call_id, self._ari).exists():
+ if not Channel(participant_call_id, self._ari, self._channel_proxy).exists():
raise ParticipantCallNotFound(participant_call_id)
participants = self._ari.bridges.get(bridgeId=adhoc_conference_id).json[
diff --git a/wazo_calld/plugins/adhoc_conferences/stasis.py b/wazo_calld/plugins/adhoc_conferences/stasis.py
index d3c6b84e..24b52d6c 100644
--- a/wazo_calld/plugins/adhoc_conferences/stasis.py
+++ b/wazo_calld/plugins/adhoc_conferences/stasis.py
@@ -15,10 +15,11 @@ ADHOC_CONFERENCE_STASIS_APP = 'adhoc_conference'
class AdhocConferencesStasis:
- def __init__(self, ari, notifier):
+ def __init__(self, ari, notifier, channel_proxy):
self._ari = ari.client
self._core_ari = ari
self._notifier = notifier
+ self._channel_proxy = channel_proxy
self._adhoc_conference_creation_lock = threading.Lock()
def _subscribe(self):
@@ -97,10 +98,10 @@ class AdhocConferencesStasis:
)
return
- bridge_helper = BridgeSnapshot(event['bridge'], self._ari)
+ bridge_helper = BridgeSnapshot(event['bridge'], self._ari, self._channel_proxy)
if is_adhoc_conference_host:
- host_channel = Channel(channel_id, self._ari)
+ host_channel = Channel(channel_id, self._ari, self._channel_proxy)
host_user_uuid = host_channel.user()
host_tenant_uuid = host_channel.tenant_uuid()
bridge_helper.global_variables.set('WAZO_HOST_CHANNEL_ID', channel_id)
@@ -118,7 +119,9 @@ class AdhocConferencesStasis:
)
self._set_host_connectedline(channel_id, adhoc_conference_id)
- participant_call = CallsService.make_call_from_channel(self._ari, channel)
+ participant_call = CallsService.make_call_from_channel(
+ self._ari, self._channel_proxy, channel
+ )
other_participant_uuids = bridge_helper.valid_user_uuids()
self._notifier.participant_joined(
adhoc_conference_id, other_participant_uuids, participant_call
@@ -138,7 +141,7 @@ class AdhocConferencesStasis:
)
continue
other_participant_call = CallsService.make_call_from_channel(
- self._ari, other_participant_channel
+ self._ari, self._channel_proxy, other_participant_channel
)
self._notifier.participant_joined(
adhoc_conference_id, [host_user_uuid], other_participant_call
@@ -173,7 +176,7 @@ class AdhocConferencesStasis:
'adhoc conference %s: channel %s left', adhoc_conference_id, channel_id
)
- bridge_helper = Bridge(adhoc_conference_id, self._ari)
+ bridge_helper = Bridge(adhoc_conference_id, self._ari, self._channel_proxy)
try:
host_user_uuid = bridge_helper.global_variables.get('WAZO_HOST_USER_UUID')
except KeyError:
@@ -256,7 +259,7 @@ class AdhocConferencesStasis:
return
logger.debug('adhoc conference %s: bridge was destroyed', bridge.id)
- bridge_helper = Bridge(bridge.id, self._ari)
+ bridge_helper = Bridge(bridge.id, self._ari, self._channel_proxy)
try:
host_user_uuid = bridge_helper.global_variables.get('WAZO_HOST_USER_UUID')
diff --git a/wazo_calld/plugins/applications/models.py b/wazo_calld/plugins/applications/models.py
index 319d916e..a8d7720a 100644
--- a/wazo_calld/plugins/applications/models.py
+++ b/wazo_calld/plugins/applications/models.py
@@ -41,9 +41,10 @@ class ApplicationNode:
class CallFormatter:
- def __init__(self, application, ari=None):
+ def __init__(self, application, ari=None, channel_proxy=None):
self._application = application
self._ari = ari
+ self._channel_proxy = channel_proxy
self._snoop_list = None
def from_channel(self, channel, variables=None, node_uuid=None):
@@ -58,7 +59,7 @@ class CallFormatter:
call.node_uuid = node_uuid
if self._ari is not None:
- channel_helper = _ChannelHelper(channel.id, self._ari)
+ channel_helper = _ChannelHelper(channel.id, self._ari, self._channel_proxy)
call.on_hold = channel_helper.on_hold()
call.is_caller = channel_helper.is_caller()
call.dialed_extension = channel_helper.dialed_extension()
@@ -110,7 +111,7 @@ class CallFormatter:
if not self._ari:
return {}
- snoop_helper = SnoopHelper(self._ari)
+ snoop_helper = SnoopHelper(self._ari, self._channel_proxy)
self._snoop_list = snoop_helper.list_(self._application)
result = {}
@@ -197,7 +198,7 @@ class _Snoop:
if old_snoop_channel:
old_snoop_channel.hangup()
- def new_snoop_channel(self, ari, whisper_mode):
+ def new_snoop_channel(self, ari, channel_proxy, whisper_mode):
logger.debug('Creating new snoop channel')
try:
snoop_channel = ari.channels.snoopChannel(
@@ -209,7 +210,7 @@ class _Snoop:
except ARINotFound:
raise NoSuchCall(self.snooped_call_id)
- _ChannelHelper(snoop_channel.id, ari).wait_until_in_stasis()
+ _ChannelHelper(snoop_channel.id, ari, channel_proxy).wait_until_in_stasis()
snoop_channel.setChannelVar(
variable=self._whisper_mode_chan_var,
@@ -278,8 +279,9 @@ class _Snoop:
class SnoopHelper:
- def __init__(self, ari):
+ def __init__(self, ari, channel_proxy):
self._ari = ari
+ self._channel_proxy = channel_proxy
def create(self, application, snooped_call_id, snooping_call_id, whisper_mode):
self.validate_ownership(application, snooped_call_id, snooping_call_id)
@@ -287,7 +289,9 @@ class SnoopHelper:
snoop = _Snoop(application, snooped_call_id, snooping_call_id)
try:
snoop.create_bridge(self._ari)
- snoop_channel = snoop.new_snoop_channel(self._ari, whisper_mode)
+ snoop_channel = snoop.new_snoop_channel(
+ self._ari, self._channel_proxy, whisper_mode
+ )
snoop.update_snoop_channel(snoop_channel)
except Exception as e:
logger.debug('Error while creating the snoop bridge, destroying it. %s', e)
@@ -303,7 +307,9 @@ class SnoopHelper:
snoop = self.get(application, snoop_uuid)
self.validate_ownership(application, snoop.snooped_call_id)
- snoop_channel = snoop.new_snoop_channel(self._ari, whisper_mode)
+ snoop_channel = snoop.new_snoop_channel(
+ self._ari, self._channel_proxy, whisper_mode
+ )
snoop.update_snoop_channel(snoop_channel)
return snoop
diff --git a/wazo_calld/plugins/applications/plugin.py b/wazo_calld/plugins/applications/plugin.py
index 2e25537b..d4036d9d 100644
--- a/wazo_calld/plugins/applications/plugin.py
+++ b/wazo_calld/plugins/applications/plugin.py
@@ -48,6 +48,7 @@ class Plugin:
token_changed_subscribe = dependencies['token_changed_subscribe']
next_token_changed_subscribe = dependencies['next_token_changed_subscribe']
pubsub = dependencies['pubsub']
+ channel_proxy = dependencies['channel_proxy']
auth_client = AuthClient(**config['auth'])
confd_client = ConfdClient(**config['confd'])
@@ -70,10 +71,12 @@ class Plugin:
notifier,
confd_apps_cache,
moh_cache,
+ channel_proxy,
)
stasis = ApplicationStasis(
ari,
+ channel_proxy,
service,
notifier,
confd_apps_cache,
diff --git a/wazo_calld/plugins/applications/services.py b/wazo_calld/plugins/applications/services.py
index 4f3c294a..958ac6b5 100644
--- a/wazo_calld/plugins/applications/services.py
+++ b/wazo_calld/plugins/applications/services.py
@@ -29,14 +29,15 @@ logger = logging.getLogger(__name__)
class ApplicationService:
- def __init__(self, ari, confd, amid, notifier, confd_apps, moh):
+ def __init__(self, ari, confd, amid, notifier, confd_apps, moh, channel_proxy):
self._ari = ari
self._amid = amid
self._notifier = notifier
self._confd = confd
self._confd_apps = confd_apps
self._moh = moh
- self._snoop_helper = SnoopHelper(self._ari)
+ self._channel_proxy = channel_proxy
+ self._snoop_helper = SnoopHelper(self._ari, self._channel_proxy)
def call_mute(self, application, call_id):
try:
@@ -46,7 +47,7 @@ class ApplicationService:
except ARINotFound:
raise NoSuchCall(call_id)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
self._notifier.call_updated(application, call)
@@ -58,7 +59,7 @@ class ApplicationService:
except ARINotFound:
raise NoSuchCall(call_id)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
self._notifier.call_updated(application, call)
@@ -73,7 +74,7 @@ class ApplicationService:
def start_user_outgoing_call(self, application, channel):
set_channel_var_sync(channel, 'WAZO_USER_OUTGOING_CALL', 'true')
variables = self.get_channel_variables(channel)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel, variables=variables)
self._notifier.user_outgoing_call_created(application, call)
@@ -274,7 +275,7 @@ class ApplicationService:
name = channel.json['name']
return name.startswith('Local/') and name.endswith(';2')
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
for channel_id in application['channel_ids']:
try:
channel = self._ari.channels.get(channelId=channel_id)
@@ -341,7 +342,7 @@ class ApplicationService:
channel = self._ari.channels.originate(**originate_kwargs)
variables = self.get_channel_variables(channel)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
return formatter.from_channel(channel, variables=variables, node_uuid=node_uuid)
def originate_user(
@@ -374,17 +375,17 @@ class ApplicationService:
def originate_answered(self, application, channel):
channel.answer()
variables = self.get_channel_variables(channel)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel, variables=variables)
self._notifier.call_initiated(application, call)
def snoop_create(
self, application, snooped_call_id, snooping_call_id, whisper_mode
):
- if not Channel(snooping_call_id, self._ari).is_in_stasis():
+ if not Channel(snooping_call_id, self._ari, self._channel_proxy).is_in_stasis():
raise CallNotInApplication(application['uuid'], snooping_call_id)
- if not Channel(snooped_call_id, self._ari).is_in_stasis():
+ if not Channel(snooped_call_id, self._ari, self._channel_proxy).is_in_stasis():
raise CallNotInApplication(application['uuid'], snooped_call_id)
snoop = self._snoop_helper.create(
diff --git a/wazo_calld/plugins/applications/stasis.py b/wazo_calld/plugins/applications/stasis.py
index a0bf3d46..0999c140 100644
--- a/wazo_calld/plugins/applications/stasis.py
+++ b/wazo_calld/plugins/applications/stasis.py
@@ -32,8 +32,9 @@ class AppNameHelper:
class ApplicationStasis:
- def __init__(self, ari, service, notifier, confd_apps, moh):
+ def __init__(self, ari, channel_proxy, service, notifier, confd_apps, moh):
self._ari = ari.client
+ self._channel_proxy = channel_proxy
self._confd_apps = confd_apps
self._moh = moh
self._core_ari = ari
@@ -77,7 +78,7 @@ class ApplicationStasis:
node = make_node_from_bridge_event(event.get('bridge'))
self._notifier.node_updated(application, node)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
self._notifier.call_updated(application, call)
@@ -128,7 +129,7 @@ class ApplicationStasis:
return
application = self._service.get_application(application_uuid)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
self._notifier.call_deleted(application, call)
@@ -152,7 +153,7 @@ class ApplicationStasis:
if moh:
set_channel_var_sync(channel, 'WAZO_MOH_UUID', str(moh['uuid']))
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
self._notifier.call_updated(application, call)
@@ -164,7 +165,7 @@ class ApplicationStasis:
application = self._service.get_application(application_uuid)
set_channel_var_sync(channel, 'WAZO_MOH_UUID', '')
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
self._notifier.call_updated(application, call)
@@ -175,7 +176,7 @@ class ApplicationStasis:
application = self._service.get_application(application_uuid)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
if channel.json['state'] == 'Up':
@@ -189,7 +190,7 @@ class ApplicationStasis:
application = self._service.get_application(application_uuid)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel)
if event['value'] == '1':
@@ -247,7 +248,7 @@ class ApplicationStasis:
application = self._service.get_application(application_uuid)
variables = self._service.get_channel_variables(channel)
- formatter = CallFormatter(application, self._ari)
+ formatter = CallFormatter(application, self._ari, self._channel_proxy)
call = formatter.from_channel(channel, variables=variables)
self._notifier.call_entered(application, call)
diff --git a/wazo_calld/plugins/applications/tests/test_stasis.py b/wazo_calld/plugins/applications/tests/test_stasis.py
index 4086d275..ddcb3a7f 100644
--- a/wazo_calld/plugins/applications/tests/test_stasis.py
+++ b/wazo_calld/plugins/applications/tests/test_stasis.py
@@ -15,6 +15,7 @@ from unittest.mock import (
)
from wazo_test_helpers.hamcrest.raises import raises
+from wazo_calld.helpers.channel_proxy import ChannelProxy
from ..stasis import ApplicationStasis
@@ -28,6 +29,7 @@ class TestApplicationStasisStartHandler(TestCase):
self.app = ApplicationStasis(
self.ari,
+ ChannelProxy(self.ari),
self.service,
self.notifier,
self.confd_apps_cache,
diff --git a/wazo_calld/plugins/calls/bus_consume.py b/wazo_calld/plugins/calls/bus_consume.py
index 665cd928..376ba93e 100644
--- a/wazo_calld/plugins/calls/bus_consume.py
+++ b/wazo_calld/plugins/calls/bus_consume.py
@@ -27,6 +27,7 @@ class CallsBusEventHandler:
xivo_uuid,
dial_echo_manager,
notifier,
+ channel_proxy,
):
self.ami = ami
self.ari = ari
@@ -36,6 +37,7 @@ class CallsBusEventHandler:
self.xivo_uuid = xivo_uuid
self.dial_echo_manager = dial_echo_manager
self.notifier = notifier
+ self._channel_proxy = channel_proxy
def subscribe(self, bus_consumer):
bus_consumer.subscribe('Newchannel', self._add_sip_call_id)
@@ -62,7 +64,7 @@ class CallsBusEventHandler:
if not event['Channel'].startswith('PJSIP/'):
return
channel_id = event['Uniqueid']
- channel = Channel(channel_id, self.ari)
+ channel = Channel(channel_id, self.ari, self._channel_proxy)
sip_call_id = channel.sip_call_id_unsafe()
if not sip_call_id:
return
@@ -89,7 +91,9 @@ class CallsBusEventHandler:
logger.debug('channel %s not found', channel_id)
return
- call = self.services.make_call_from_channel(self.ari, channel)
+ call = self.services.make_call_from_channel(
+ self.ari, self._channel_proxy, channel
+ )
if self._call_direction_unknown(call):
call.direction = self.services.conversation_direction_from_channels(
self.ari, [channel.id]
@@ -113,7 +117,9 @@ class CallsBusEventHandler:
except ARINotFound:
logger.debug('channel %s not found', channel_id)
return
- call = self.services.make_call_from_channel(self.ari, channel)
+ call = self.services.make_call_from_channel(
+ self.ari, self._channel_proxy, channel
+ )
self.notifier.call_updated(call)
def _relay_channel_answered(self, event):
@@ -135,7 +141,9 @@ class CallsBusEventHandler:
except ARINotFound:
logger.debug('channel %s not found', channel_id)
return
- call = self.services.make_call_from_channel(self.ari, channel)
+ call = self.services.make_call_from_channel(
+ self.ari, self._channel_proxy, channel
+ )
if self._call_direction_unknown(call):
call.direction = self.services.conversation_direction_from_channels(
self.ari, [channel.id]
@@ -149,7 +157,7 @@ class CallsBusEventHandler:
self.collectd.publish(ChannelEndedCollectdEvent())
def _partial_call_from_channel_id(self, channel_id):
- channel = Channel(channel_id, self.ari)
+ channel = Channel(channel_id, self.ari, self._channel_proxy)
call = Call(channel.id)
call.user_uuid = channel.user()
call.tenant_uuid = channel.tenant_uuid()
@@ -261,7 +269,9 @@ class CallsBusEventHandler:
self.ari, [channel.id for channel in participant_channels]
)
for channel in participant_channels:
- call = self.services.make_call_from_channel(self.ari, channel)
+ call = self.services.make_call_from_channel(
+ self.ari, self._channel_proxy, channel
+ )
if call.direction != call_direction:
self._set_conversation_direction_cache(channel.id, call_direction)
call.direction = call_direction
@@ -305,7 +315,9 @@ class CallsBusEventHandler:
self.ari, [channel.id for channel in participant_channels]
)
for channel in participant_channels:
- call = self.services.make_call_from_channel(self.ari, channel)
+ call = self.services.make_call_from_channel(
+ self.ari, self._channel_proxy, channel
+ )
if call.direction != call_direction:
self._set_conversation_direction_cache(channel.id, call_direction)
call.direction = call_direction
diff --git a/wazo_calld/plugins/calls/plugin.py b/wazo_calld/plugins/calls/plugin.py
index 0f344964..361278db 100644
--- a/wazo_calld/plugins/calls/plugin.py
+++ b/wazo_calld/plugins/calls/plugin.py
@@ -45,6 +45,7 @@ class Plugin:
collectd = dependencies['collectd']
token_changed_subscribe = dependencies['token_changed_subscribe']
config = dependencies['config']
+ channel_proxy = dependencies['channel_proxy']
amid_client = AmidClient(**config['amid'])
token_changed_subscribe(amid_client.set_token)
@@ -66,6 +67,7 @@ class Plugin:
dial_echo_manager,
phoned_client,
notifier,
+ channel_proxy,
)
calls_stasis = CallsStasis(
@@ -76,6 +78,7 @@ class Plugin:
notifier,
config['uuid'],
amid_client,
+ channel_proxy,
)
startup_callback_collector = CallbackCollector()
@@ -91,6 +94,7 @@ class Plugin:
config['uuid'],
dial_echo_manager,
notifier,
+ channel_proxy,
)
calls_bus_event_handler.subscribe(bus_consumer)
diff --git a/wazo_calld/plugins/calls/services.py b/wazo_calld/plugins/calls/services.py
index 844634ab..a2f4c6bb 100644
--- a/wazo_calld/plugins/calls/services.py
+++ b/wazo_calld/plugins/calls/services.py
@@ -46,6 +46,7 @@ class CallsService:
dial_echo_manager,
phoned_client,
notifier,
+ channel_proxy,
):
self._ami = amid_client
self._ari_config = ari_config
@@ -55,6 +56,7 @@ class CallsService:
self._phoned_client = phoned_client
self._notifier = notifier
self._state_persistor = ReadOnlyStatePersistor(self._ari)
+ self._channel_proxy = channel_proxy
def list_calls(self, application_filter=None, application_instance_filter=None):
channels = self._ari.channels.list()
@@ -87,7 +89,10 @@ class CallsService:
app_instance_channels.append(channel)
channels = app_instance_channels
- return [self.make_call_from_channel(self._ari, channel) for channel in channels]
+ return [
+ self.make_call_from_channel(self._ari, self._channel_proxy, channel)
+ for channel in channels
+ ]
def list_calls_user(
self, user_uuid, application_filter=None, application_instance_filter=None
@@ -97,7 +102,7 @@ class CallsService:
call
for call in calls
if call.user_uuid == user_uuid
- and not Channel(call.id_, self._ari).is_local()
+ and not Channel(call.id_, self._ari, self._channel_proxy).is_local()
]
def originate(self, request):
@@ -221,7 +226,7 @@ class CallsService:
variables={'variables': variables},
)
- call = self.make_call_from_channel(self._ari, channel)
+ call = self.make_call_from_channel(self._ari, self._channel_proxy, channel)
call.dialed_extension = request['destination']['extension']
return call
@@ -257,7 +262,7 @@ class CallsService:
except ARINotFound:
raise NoSuchCall(channel_id)
- return self.make_call_from_channel(self._ari, channel)
+ return self.make_call_from_channel(self._ari, self._channel_proxy, channel)
def hangup(self, call_id):
channel_id = call_id
@@ -279,7 +284,7 @@ class CallsService:
# NOTE(fblackburn): asterisk should send back an event
# instead of falsy pretend that channel is muted
- call = self.make_call_from_channel(self._ari, channel)
+ call = self.make_call_from_channel(self._ari, self._channel_proxy, channel)
self._notifier.call_updated(call)
def unmute(self, call_id):
@@ -293,7 +298,7 @@ class CallsService:
# NOTE(fblackburn): asterisk should send back an event
# instead of falsy pretend that channel is unmuted
- call = self.make_call_from_channel(self._ari, channel)
+ call = self.make_call_from_channel(self._ari, self._channel_proxy, channel)
self._notifier.call_updated(call)
def mute_user(self, call_id, user_uuid):
@@ -340,9 +345,9 @@ class CallsService:
return new_channel.id
@staticmethod
- def make_call_from_channel(ari, channel):
+ def make_call_from_channel(ari, channel_proxy, channel):
channel_variables = channel.json.get('channelvars', {})
- channel_helper = Channel(channel.id, ari)
+ channel_helper = Channel(channel.id, ari, channel_proxy)
call = Call(channel.id)
call.conversation_id = channel_helper.conversation_id()
call.creation_time = channel.json['creationtime']
@@ -391,10 +396,10 @@ class CallsService:
return call
@staticmethod
- def channel_destroyed_event(ari, event):
+ def channel_destroyed_event(ari, channel_proxy, event):
channel = event['channel']
channel_id = channel.get('id')
- channel_helper = Channel(channel_id, ari)
+ channel_helper = Channel(channel_id, ari, channel_proxy)
channel_variables = event['channel']['channelvars']
conversation_id = channel_variables.get('CHANNEL(linkedid)')
connected = channel.get('connected')
@@ -664,7 +669,7 @@ class CallsService:
]
def _verify_user(self, call_id, user_uuid):
- channel = Channel(call_id, self._ari)
+ channel = Channel(call_id, self._ari, self._channel_proxy)
if not channel.exists() or channel.is_local():
raise NoSuchCall(call_id)
diff --git a/wazo_calld/plugins/calls/stasis.py b/wazo_calld/plugins/calls/stasis.py
index 5f4d6656..bc8a6ce6 100644
--- a/wazo_calld/plugins/calls/stasis.py
+++ b/wazo_calld/plugins/calls/stasis.py
@@ -26,7 +26,15 @@ logger = logging.getLogger(__name__)
class CallsStasis:
def __init__(
- self, ari, collectd, bus_publisher, services, notifier, xivo_uuid, amid_client
+ self,
+ ari,
+ collectd,
+ bus_publisher,
+ services,
+ notifier,
+ xivo_uuid,
+ amid_client,
+ channel_proxy,
):
self.ari = ari.client
self._core_ari = ari
@@ -40,6 +48,7 @@ class CallsStasis:
self.state_persistor = StatePersistor(self.ari)
self.xivo_uuid = xivo_uuid
self.ami = amid_client
+ self._channel_proxy = channel_proxy
def initialize(self):
self._subscribe()
@@ -49,6 +58,7 @@ class CallsStasis:
self.ari.on_channel_event('StasisStart', self.stasis_start)
self.ari.on_channel_event('ChannelDestroyed', self.channel_destroyed)
self.ari.on_channel_event('ChannelDestroyed', self.relay_channel_hung_up)
+ self.ari.on_channel_event('ChannelDestroyed', self._channel_proxy.on_hang_up)
self.ari.on_application_registered(
DEFAULT_APPLICATION_NAME, self.subscribe_to_all_channel_events
)
@@ -126,5 +136,7 @@ class CallsStasis:
logger.debug('Ignoring local channel hangup: %s', channel_id)
return
logger.debug('Relaying to bus: channel %s ended', channel_id)
- call = self.services.channel_destroyed_event(self.ari, event)
+ call = self.services.channel_destroyed_event(
+ self.ari, self._channel_proxy, event
+ )
self.notifier.call_ended(call, event['cause'])
diff --git a/wazo_calld/plugins/calls/tests/test_bus_consume.py b/wazo_calld/plugins/calls/tests/test_bus_consume.py
index 9cd91705..4feab6bf 100644
--- a/wazo_calld/plugins/calls/tests/test_bus_consume.py
+++ b/wazo_calld/plugins/calls/tests/test_bus_consume.py
@@ -6,6 +6,8 @@ from unittest.mock import Mock
from hamcrest import assert_that, calling, not_, raises
+from wazo_calld.helpers.channel_proxy import ChannelProxy
+
from ..bus_consume import CallsBusEventHandler
from ..exceptions import NoSuchCall
@@ -29,6 +31,7 @@ class TestCallsBusEventHandler(TestCase):
xivo_uuid,
dial_echo_manager,
notifier,
+ ChannelProxy(ari),
)
def test_relay_channel_answered_channel_is_gone(self):
diff --git a/wazo_calld/plugins/calls/tests/test_services.py b/wazo_calld/plugins/calls/tests/test_services.py
index fd6d53c1..ff6357ff 100644
--- a/wazo_calld/plugins/calls/tests/test_services.py
+++ b/wazo_calld/plugins/calls/tests/test_services.py
@@ -5,14 +5,24 @@ from hamcrest import assert_that, equal_to
from unittest.mock import Mock, patch
from unittest import TestCase
+from wazo_calld.helpers.channel_proxy import ChannelProxy
+
from ..services import CallsService
class TestServices(TestCase):
def setUp(self):
self.ari = Mock()
+ self.channel_proxy = ChannelProxy(self.ari)
self.services = CallsService(
- Mock(), Mock(), self.ari, Mock(), Mock(), Mock(), Mock()
+ Mock(),
+ Mock(),
+ self.ari,
+ Mock(),
+ Mock(),
+ Mock(),
+ Mock(),
+ self.channel_proxy,
)
self.example_to_fit = {
@@ -69,7 +79,9 @@ class TestServices(TestCase):
event = self.example_to_fit
event['channel']['channelvars'] = {}
- call = self.services.channel_destroyed_event(self.ari, event)
+ call = self.services.channel_destroyed_event(
+ self.ari, self.channel_proxy, event
+ )
assert_that(call.user_uuid, equal_to(None))
assert_that(call.dialed_extension, equal_to(None))
@@ -84,7 +96,9 @@ class TestServices(TestCase):
event = self.example_to_fit
event['channel']['channelvars'] = {'XIVO_USERUUID': 'new_useruuid'}
- call = self.services.channel_destroyed_event(self.ari, event)
+ call = self.services.channel_destroyed_event(
+ self.ari, self.channel_proxy, event
+ )
assert_that(call.user_uuid, equal_to('new_useruuid'))
@@ -101,7 +115,9 @@ class TestServices(TestCase):
'WAZO_DEREFERENCED_USERUUID': 'new-user-uuid',
}
- call = self.services.channel_destroyed_event(self.ari, event)
+ call = self.services.channel_destroyed_event(
+ self.ari, self.channel_proxy, event
+ )
assert_that(call.user_uuid, equal_to('new-user-uuid'))
@@ -112,7 +128,9 @@ class TestServices(TestCase):
channel_ids.return_value = []
event = self.example_to_fit
creation_time = event['channel']['creationtime']
- call = self.services.channel_destroyed_event(self.ari, event)
+ call = self.services.channel_destroyed_event(
+ self.ari, self.channel_proxy, event
+ )
assert_that(call.creation_time, equal_to(creation_time))
@@ -122,7 +140,9 @@ class TestServices(TestCase):
def test_direction_of_call_to_who_is_caller(self, channel_ids):
channel_ids.return_value = []
event = self.example_to_fit
- call = self.services.channel_destroyed_event(self.ari, event)
+ call = self.services.channel_destroyed_event(
+ self.ari, self.channel_proxy, event
+ )
assert_that(call.is_caller, equal_to(True))
diff --git a/wazo_calld/plugins/conferences/plugin.py b/wazo_calld/plugins/conferences/plugin.py
index 746c436a..2f9f0a5c 100644
--- a/wazo_calld/plugins/conferences/plugin.py
+++ b/wazo_calld/plugins/conferences/plugin.py
@@ -25,6 +25,7 @@ class Plugin:
bus_publisher = dependencies['bus_publisher']
config = dependencies['config']
token_changed_subscribe = dependencies['token_changed_subscribe']
+ channel_proxy = dependencies['channel_proxy']
amid_client = AmidClient(**config['amid'])
confd_client = ConfdClient(**config['confd'])
@@ -32,7 +33,12 @@ class Plugin:
token_changed_subscribe(amid_client.set_token)
token_changed_subscribe(confd_client.set_token)
- conferences_service = ConferencesService(amid_client, ari.client, confd_client)
+ conferences_service = ConferencesService(
+ amid_client,
+ ari.client,
+ channel_proxy,
+ confd_client,
+ )
notifier = ConferencesNotifier(bus_publisher)
bus_event_handler = ConferencesBusEventHandler(
confd_client, notifier, conferences_service
diff --git a/wazo_calld/plugins/conferences/services.py b/wazo_calld/plugins/conferences/services.py
index 4803da4f..9eb0e4a2 100644
--- a/wazo_calld/plugins/conferences/services.py
+++ b/wazo_calld/plugins/conferences/services.py
@@ -29,10 +29,11 @@ logger = logging.getLogger(__name__)
class ConferencesService:
- def __init__(self, amid, ari, confd):
+ def __init__(self, amid, ari, channel_proxy, confd):
self._amid = amid
self._ari = ari
self._confd = confd
+ self._channel_proxy = channel_proxy
def list_participants(self, tenant_uuid, conference_id):
if not Conference(tenant_uuid, conference_id, self._confd).exists():
@@ -74,7 +75,9 @@ class ConferencesService:
'language': participant_list_item['Language'],
'call_id': participant_list_item['Uniqueid'],
'user_uuid': Channel(
- participant_list_item['Uniqueid'], self._ari
+ participant_list_item['Uniqueid'],
+ self._ari,
+ self._channel_proxy,
).user(),
}
try:
diff --git a/wazo_calld/plugins/dial_mobile/plugin.py b/wazo_calld/plugins/dial_mobile/plugin.py
index a6bba164..8904b7ec 100644
--- a/wazo_calld/plugins/dial_mobile/plugin.py
+++ b/wazo_calld/plugins/dial_mobile/plugin.py
@@ -19,6 +19,7 @@ class Plugin:
token_changed_subscribe = dependencies['token_changed_subscribe']
config = dependencies['config']
bus_publisher = dependencies['bus_publisher']
+ channel_proxy = dependencies['channel_proxy']
amid_client = AmidClient(**config['amid'])
token_changed_subscribe(amid_client.set_token)
@@ -27,7 +28,7 @@ class Plugin:
token_changed_subscribe(auth_client.set_token)
notifier = Notifier(bus_publisher)
- service = DialMobileService(ari, notifier, amid_client, auth_client)
+ service = DialMobileService(ari, channel_proxy, notifier, amid_client, auth_client)
stasis = DialMobileStasis(ari, service)
event_handler = EventHandler(service)
diff --git a/wazo_calld/plugins/dial_mobile/services.py b/wazo_calld/plugins/dial_mobile/services.py
index 55a6ca78..7ba0b2a1 100644
--- a/wazo_calld/plugins/dial_mobile/services.py
+++ b/wazo_calld/plugins/dial_mobile/services.py
@@ -147,8 +147,9 @@ class _PollingContactDialer:
class DialMobileService:
- def __init__(self, ari, notifier, amid_client, auth_client):
+ def __init__(self, ari, channel_proxy, notifier, amid_client, auth_client):
self._ari = ari.client
+ self._channel_proxy = channel_proxy
self._auth_client = auth_client
self._amid_client = amid_client
self._contact_dialers = {}
@@ -221,7 +222,7 @@ class DialMobileService:
del self._contact_dialers[key]
def clean_bridge(self, bridge_id):
- bridge_helper = Bridge(bridge_id, self._ari)
+ bridge_helper = Bridge(bridge_id, self._ari, self._channel_proxy)
if bridge_helper.has_lone_channel():
logger.debug(
'dial_mobile: bridge %s: only one participant left, hanging up',
diff --git a/wazo_calld/plugins/meetings/plugin.py b/wazo_calld/plugins/meetings/plugin.py
index afdb673d..9469c4b0 100644
--- a/wazo_calld/plugins/meetings/plugin.py
+++ b/wazo_calld/plugins/meetings/plugin.py
@@ -24,6 +24,7 @@ class Plugin:
bus_publisher = dependencies['bus_publisher']
config = dependencies['config']
token_changed_subscribe = dependencies['token_changed_subscribe']
+ channel_proxy = dependencies['channel_proxy']
amid_client = AmidClient(**config['amid'])
confd_client = ConfdClient(**config['confd'])
@@ -32,7 +33,11 @@ class Plugin:
token_changed_subscribe(confd_client.set_token)
meetings_service = MeetingsService(
- amid_client, ari.client, confd_client, config
+ amid_client,
+ ari.client,
+ confd_client,
+ config,
+ channel_proxy,
)
notifier = MeetingsNotifier(bus_publisher)
bus_event_handler = MeetingsBusEventHandler(
diff --git a/wazo_calld/plugins/meetings/services.py b/wazo_calld/plugins/meetings/services.py
index 759091f0..830b4ef6 100644
--- a/wazo_calld/plugins/meetings/services.py
+++ b/wazo_calld/plugins/meetings/services.py
@@ -24,11 +24,12 @@ logger = logging.getLogger(__name__)
class MeetingsService:
- def __init__(self, amid, ari, confd, config):
+ def __init__(self, amid, ari, confd, config, channel_proxy):
self._amid = amid
self._ari = ari
self._confd = confd
self._max_participants = config['max_meeting_participants']
+ self._channel_proxy = channel_proxy
def get_status(self, meeting_uuid):
tenant_uuid = None
@@ -101,7 +102,9 @@ class MeetingsService:
'caller_id_number': participant_list_item['CallerIDNum'],
'call_id': participant_list_item['Uniqueid'],
'user_uuid': Channel(
- participant_list_item['Uniqueid'], self._ari
+ participant_list_item['Uniqueid'],
+ self._ari,
+ self._channel_proxy,
).user(),
}
try:
@@ -149,7 +152,7 @@ class MeetingsService:
if not meeting.exists():
raise NoSuchMeeting(tenant_uuid, meeting_uuid)
- channel = Channel(participant_id, self._ari)
+ channel = Channel(participant_id, self._ari, self._channel_proxy)
try:
self._amid.action(
'ConfbridgeKick',
diff --git a/wazo_calld/plugins/relocates/plugin.py b/wazo_calld/plugins/relocates/plugin.py
index 61d573e9..2ef398b0 100644
--- a/wazo_calld/plugins/relocates/plugin.py
+++ b/wazo_calld/plugins/relocates/plugin.py
@@ -25,6 +25,7 @@ class Plugin:
bus_publisher = dependencies['bus_publisher']
config = dependencies['config']
token_changed_subscribe = dependencies['token_changed_subscribe']
+ channel_proxy = dependencies['channel_proxy']
amid_client = AmidClient(**config['amid'])
confd_client = ConfdClient(**config['confd'])
@@ -33,11 +34,19 @@ class Plugin:
token_changed_subscribe(confd_client.set_token)
relocates = RelocateCollection()
- state_factory = StateFactory(state_index, amid_client, ari.client)
+ state_factory = StateFactory(
+ state_index, amid_client, ari.client, channel_proxy
+ )
notifier = RelocatesNotifier(bus_publisher)
relocates_service = RelocatesService(
- amid_client, ari.client, confd_client, notifier, relocates, state_factory
+ amid_client,
+ ari.client,
+ confd_client,
+ notifier,
+ relocates,
+ state_factory,
+ channel_proxy,
)
relocates_stasis = RelocatesStasis(ari, relocates)
diff --git a/wazo_calld/plugins/relocates/services.py b/wazo_calld/plugins/relocates/services.py
index e73cab31..8f250a6f 100644
--- a/wazo_calld/plugins/relocates/services.py
+++ b/wazo_calld/plugins/relocates/services.py
@@ -132,7 +132,9 @@ class ExtensionDestination(Destination):
class RelocatesService:
- def __init__(self, amid, ari, confd_client, notifier, relocates, state_factory):
+ def __init__(
+ self, amid, ari, confd_client, notifier, relocates, state_factory, channel_proxy
+ ):
self.ari = ari
self.confd_client = confd_client
self.notifier = notifier
@@ -140,6 +142,7 @@ class RelocatesService:
self.destination_factory = DestinationFactory(amid, ari)
self.relocates = relocates
self.duplicate_relocate_lock = threading.Lock()
+ self._channel_proxy = channel_proxy
def list_from_user(self, user_uuid):
return [
@@ -159,14 +162,16 @@ class RelocatesService:
):
try:
relocated_channel = Channel(
- initiator_call, self.ari
+ initiator_call,
+ self.ari,
+ self._channel_proxy,
).only_connected_channel()
except TooManyChannels as e:
raise TooManyChannelCandidates(e.channels)
except NotEnoughChannels:
raise RelocateCreationError('relocated channel not found')
- initiator_channel = Channel(initiator_call, self.ari)
+ initiator_channel = Channel(initiator_call, self.ari, self._channel_proxy)
if not initiator_channel.exists():
details = {'initiator_call': initiator_call}
raise RelocateCreationError('initiator call not found', details)
@@ -210,7 +215,7 @@ class RelocatesService:
auto_answer,
user_uuid,
):
- initiator_channel = Channel(initiator_call, self.ari)
+ initiator_channel = Channel(initiator_call, self.ari, self._channel_proxy)
user = User(user_uuid, self.confd_client)
variables = {}
diff --git a/wazo_calld/plugins/relocates/state.py b/wazo_calld/plugins/relocates/state.py
index 2ac46eb0..5d472380 100644
--- a/wazo_calld/plugins/relocates/state.py
+++ b/wazo_calld/plugins/relocates/state.py
@@ -71,18 +71,19 @@ class RelocateCompleter:
class StateFactory:
- def __init__(self, index, amid, ari):
+ def __init__(self, index, amid, ari, channel_proxy):
self._index = index
- self._state_args = [amid, ari]
+ self._state_args = [amid, ari, channel_proxy]
def make(self, name):
return self._index[name](*self._state_args)
class RelocateState:
- def __init__(self, amid, ari):
+ def __init__(self, amid, ari, channel_proxy):
self._amid = amid
self._ari = ari
+ self._channel_proxy = channel_proxy
@state
@@ -128,7 +129,9 @@ class RelocateStateRecipientRing(RelocateState):
relocate.events.publish('answered', relocate)
if 'answer' in relocate.completions:
completer = RelocateCompleter(self._amid, self._ari)
- if Channel(relocate.relocated_channel, self._ari).is_in_stasis():
+ if Channel(
+ relocate.relocated_channel, self._ari, self._channel_proxy
+ ).is_in_stasis():
completer.bridge(relocate)
try:
self._ari.channels.hangup(channelId=relocate.initiator_channel)
@@ -171,7 +174,9 @@ class RelocateStateWaitingForCompletion(RelocateState):
def complete(self, relocate):
completer = RelocateCompleter(self._amid, self._ari)
- if Channel(relocate.relocated_channel, self._ari).is_in_stasis():
+ if Channel(
+ relocate.relocated_channel, self._ari, self._channel_proxy
+ ).is_in_stasis():
completer.bridge(relocate)
try:
self._ari.channels.hangup(channelId=relocate.initiator_channel)
diff --git a/wazo_calld/plugins/switchboards/plugin.py b/wazo_calld/plugins/switchboards/plugin.py
index 08177c54..c5b5bbae 100644
--- a/wazo_calld/plugins/switchboards/plugin.py
+++ b/wazo_calld/plugins/switchboards/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2017-2021 The Wazo Authors (see the AUTHORS file)
+# Copyright 2017-2023 The Wazo Authors (see the AUTHORS file)
# SPDX-License-Identifier: GPL-3.0-or-later
from wazo_confd_client import Client as ConfdClient
@@ -32,6 +32,7 @@ class Plugin:
config = dependencies['config']
token_changed_subscribe = dependencies['token_changed_subscribe']
next_token_changed_subscribe = dependencies['next_token_changed_subscribe']
+ channel_proxy = dependencies['channel_proxy']
confd_client = ConfdClient(**config['confd'])
switchboard_get_cache = ConfdClientGetUUIDCacheDecorator(
@@ -51,7 +52,11 @@ class Plugin:
switchboards_notifier = SwitchboardsNotifier(bus_publisher)
switchboards_service = SwitchboardsService(
- ari.client, asyncio, confd_client, switchboards_notifier
+ ari.client,
+ asyncio,
+ confd_client,
+ switchboards_notifier,
+ channel_proxy,
)
switchboards_stasis = SwitchboardsStasis(
diff --git a/wazo_calld/plugins/switchboards/services.py b/wazo_calld/plugins/switchboards/services.py
index 5a7adcca..3145d4ea 100644
--- a/wazo_calld/plugins/switchboards/services.py
+++ b/wazo_calld/plugins/switchboards/services.py
@@ -34,11 +34,12 @@ logger = logging.getLogger(__name__)
class SwitchboardsService:
- def __init__(self, ari, asyncio, confd, notifier):
+ def __init__(self, ari, asyncio, confd, notifier, channel_proxy):
self._ari = ari
self._asyncio = asyncio
self._confd = confd
self._notifier = notifier
+ self._channel_proxy = channel_proxy
def queued_calls(self, tenant_uuid, switchboard_uuid):
logger.debug(
@@ -90,7 +91,9 @@ class SwitchboardsService:
calls = self.queued_calls(tenant_uuid, switchboard_uuid)
self._notifier.queued_calls(tenant_uuid, switchboard_uuid, calls)
- noanswer_timeout = Channel(channel_id, self._ari).switchboard_timeout()
+ noanswer_timeout = Channel(
+ channel_id, self._ari, self._channel_proxy
+ ).switchboard_timeout()
if not noanswer_timeout:
logger.debug(
'Switchboard %s: ignoring no answer timeout = %s',
@@ -100,7 +103,9 @@ class SwitchboardsService:
return
noanswer_fallback_action = Channel(
- channel_id, self._ari
+ channel_id,
+ self._ari,
+ self._channel_proxy,
).switchboard_noanswer_fallback_action()
if not noanswer_fallback_action:
logger.debug(
diff --git a/wazo_calld/plugins/switchboards/tests/test_services.py b/wazo_calld/plugins/switchboards/tests/test_services.py
index 3b3ac31f..7e4f43b6 100644
--- a/wazo_calld/plugins/switchboards/tests/test_services.py
+++ b/wazo_calld/plugins/switchboards/tests/test_services.py
@@ -5,6 +5,7 @@ from unittest import TestCase
from unittest.mock import Mock, sentinel as s
from wazo_calld.plugins.switchboards.services import SwitchboardsService
+from wazo_calld.helpers.channel_proxy import ChannelProxy
class TestSwitchboardService(TestCase):
@@ -13,9 +14,14 @@ class TestSwitchboardService(TestCase):
self.asyncio = Mock()
self.confd = Mock()
self.notifier = Mock()
+ self.channel_proxy = ChannelProxy(self.ari)
self.service = SwitchboardsService(
- self.ari, self.asyncio, self.confd, self.notifier
+ self.ari,
+ self.asyncio,
+ self.confd,
+ self.notifier,
+ self.channel_proxy,
)
def test_moh_on_new_queued_call_when_defined(self):
diff --git a/wazo_calld/plugins/transfers/plugin.py b/wazo_calld/plugins/transfers/plugin.py
index 6030de55..10911c7d 100644
--- a/wazo_calld/plugins/transfers/plugin.py
+++ b/wazo_calld/plugins/transfers/plugin.py
@@ -29,6 +29,7 @@ class Plugin:
bus_publisher = dependencies['bus_publisher']
config = dependencies['config']
token_changed_subscribe = dependencies['token_changed_subscribe']
+ channel_proxy = dependencies['channel_proxy']
amid_client = AmidClient(**config['amid'])
confd_client = ConfdClient(**config['confd'])
@@ -46,6 +47,7 @@ class Plugin:
state_factory,
state_persistor,
transfer_lock,
+ channel_proxy,
)
transfers_stasis = TransfersStasis(
@@ -55,6 +57,7 @@ class Plugin:
state_factory,
state_persistor,
config['uuid'],
+ channel_proxy,
)
startup_callback_collector = CallbackCollector()
@@ -66,6 +69,7 @@ class Plugin:
state_factory.set_dependencies(
amid_client,
ari.client,
+ channel_proxy,
notifier,
transfers_service,
state_persistor,
diff --git a/wazo_calld/plugins/transfers/services.py b/wazo_calld/plugins/transfers/services.py
index b74bad3d..bc869e83 100644
--- a/wazo_calld/plugins/transfers/services.py
+++ b/wazo_calld/plugins/transfers/services.py
@@ -36,6 +36,7 @@ class TransfersService:
state_factory,
state_persistor,
transfer_lock,
+ channel_proxy,
):
self.amid_client = amid_client
self.ari = ari
@@ -43,6 +44,7 @@ class TransfersService:
self.state_persistor = state_persistor
self.state_factory = state_factory
self.transfer_lock = transfer_lock
+ self._channel_proxy = channel_proxy
def list_from_user(self, user_uuid):
transfers = self.state_persistor.list()
@@ -66,8 +68,8 @@ class TransfersService:
raise TransferAlreadyStarted(initiator_call)
if not (
- Channel(transferred_call, self.ari).is_in_stasis()
- and Channel(initiator_call, self.ari).is_in_stasis()
+ Channel(transferred_call, self.ari, self._channel_proxy).is_in_stasis()
+ and Channel(initiator_call, self.ari, self._channel_proxy).is_in_stasis()
):
transfer_state = self.state_factory.make_from_class(
TransferStateReadyNonStasis
@@ -94,15 +96,17 @@ class TransfersService:
return new_state.transfer
def create_from_user(self, initiator_call, exten, flow, timeout, user_uuid):
- if not Channel(initiator_call, self.ari).exists():
+ if not Channel(initiator_call, self.ari, self._channel_proxy).exists():
raise TransferCreationError('initiator channel not found')
- if Channel(initiator_call, self.ari).user() != user_uuid:
+ if Channel(initiator_call, self.ari, self._channel_proxy).user() != user_uuid:
raise UserPermissionDenied(user_uuid, {'call': initiator_call})
try:
transferred_call = (
- Channel(initiator_call, self.ari).only_connected_channel().id
+ Channel(initiator_call, self.ari, self._channel_proxy)
+ .only_connected_channel()
+ .id
)
except TooManyChannels as e:
raise TooManyTransferredCandidates(e.channels)
diff --git a/wazo_calld/plugins/transfers/stasis.py b/wazo_calld/plugins/transfers/stasis.py
index 6271c750..a9509e31 100644
--- a/wazo_calld/plugins/transfers/stasis.py
+++ b/wazo_calld/plugins/transfers/stasis.py
@@ -27,7 +27,14 @@ logger = logging.getLogger(__name__)
class TransfersStasis:
def __init__(
- self, amid_client, ari, services, state_factory, state_persistor, xivo_uuid
+ self,
+ amid_client,
+ ari,
+ services,
+ state_factory,
+ state_persistor,
+ xivo_uuid,
+ channel_proxy,
):
self.ari = ari.client
self._core_ari = ari
@@ -40,6 +47,7 @@ class TransfersStasis:
self.hangup_pubsub.set_exception_handler(self.invalid_event)
self.state_factory = state_factory
self.state_persistor = state_persistor
+ self._channel_proxy = channel_proxy
def initialize(self):
self._subscribe()
@@ -123,13 +131,19 @@ class TransfersStasis:
logger.debug('Processing lost hangups since last stop...')
for transfer in transfers:
transfer_state = self.state_factory.make(transfer)
- if not Channel(transfer.transferred_call, self.ari).exists():
+ if not Channel(
+ transfer.transferred_call, self.ari, self._channel_proxy
+ ).exists():
logger.debug('Transferred hangup from transfer %s', transfer.id)
transfer_state = transfer_state.transferred_hangup()
- if not Channel(transfer.initiator_call, self.ari).exists():
+ if not Channel(
+ transfer.initiator_call, self.ari, self._channel_proxy
+ ).exists():
logger.debug('Initiator hangup from transfer %s', transfer.id)
transfer_state = transfer_state.initiator_hangup()
- if not Channel(transfer.recipient_call, self.ari).exists():
+ if not Channel(
+ transfer.recipient_call, self.ari, self._channel_proxy
+ ).exists():
logger.debug('Recipient hangup from transfer %s', transfer.id)
transfer_state = transfer_state.recipient_hangup()
logger.debug('Done.')
@@ -142,7 +156,9 @@ class TransfersStasis:
transfer_state = self.state_factory.make(transfer)
if (
transfer_state.name == TransferStatus.ringback
- and Channel(transfer.recipient_call, self.ari).exists()
+ and Channel(
+ transfer.recipient_call, self.ari, self._channel_proxy
+ ).exists()
):
channel = self.ari.channels.get(channelId=transfer.recipient_call)
if channel.json['state'] != 'Up':
diff --git a/wazo_calld/plugins/transfers/state.py b/wazo_calld/plugins/transfers/state.py
index ae703d27..30f220ef 100644
--- a/wazo_calld/plugins/transfers/state.py
+++ b/wazo_calld/plugins/transfers/state.py
@@ -18,9 +18,10 @@ logger = logging.getLogger(__name__)
class StateFactory:
- def __init__(self, ari=None):
+ def __init__(self, ari=None, channel_proxy=None):
self._state_constructors = {}
self._ari = ari
+ self._channel_proxy = channel_proxy
self._configured = False
def set_dependencies(self, *dependencies):
@@ -69,6 +70,7 @@ class TransferState:
self,
amid,
ari,
+ channel_proxy,
notifier,
services,
state_persistor,
@@ -77,6 +79,7 @@ class TransferState:
):
self._amid = amid
self._ari = ari
+ self._channel_proxy = channel_proxy
self._notifier = notifier
self._services = services
self._state_persistor = state_persistor
@@ -88,6 +91,7 @@ class TransferState:
new_state = cls(
other_state._amid,
other_state._ari,
+ other_state._channel_proxy,
other_state._notifier,
other_state._services,
other_state._state_persistor,
@@ -208,7 +212,7 @@ class TransferStateReady(TransferState):
variables,
timeout,
):
- channel = Channel(initiator_channel.id, self._ari)
+ channel = Channel(initiator_channel.id, self._ari, self._channel_proxy)
initiator_uuid = channel.user()
initiator_tenant_uuid = channel.tenant_uuid()
if initiator_uuid is None:
@@ -279,7 +283,7 @@ class TransferStateReadyNonStasis(TransferState):
variables,
timeout,
):
- channel = Channel(initiator_channel.id, self._ari)
+ channel = Channel(initiator_channel.id, self._ari, self._channel_proxy)
initiator_uuid = channel.user()
initiator_tenant_uuid = channel.tenant_uuid()
if initiator_uuid is None:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment