Skip to content

Commit 7058612

Browse files
authored
Adding SIP routing functionality to PhoneNumbers SDK (Azure#22805)
* Initial commit * Copied shared files * Added basic functionality to the sip client. * Copied shared folder to get the utilities. Implemented sample files. Changed naming in client * Modified function comments and added class comment for _sip_routing_client. * Fixed kwargs propagation * Changed sample file to pull parameteres from environment variables. * Changed get SIP configuration sample to be a class to align with the update samples. Changed naming of the update samples class. * Implemented basic tests for the SIP client * Removed unused import * Fixed comment. * Renamed variables dut_client to test_client. * Merge from original repo * Feature/communication sip configuration dev/basic client functionality (#3) Adding async client. * Updated from original (Azure#4) Updated from main repo. * Fixing pylint * Changed value error to be compatible with python 2. * Reverted changes for pylint. * Fixed dev requirements and MANIFEST * Fixing async tests. Fixing comments. * Removed async mock to be compatible with the builds. * Fixing test failures for Ubuntu and Mac * Changed versions for python. Fixed pylint issue in version. * Modified _version file to prevent path errors. * Added newline. * Downgraded six version to match the frozen requirements. * Fixed async test errors by excluding asynchronous tests for python 2.7. * Regenerated by autorest * Updated swagger definition. * Squashed commit of the following: commit 3d7c16a5355a6461a4e688e89410a735dfdcfcce Author: Jiri Burant <[email protected]> Date: Mon Jun 7 17:50:06 2021 +0200 Added e2e and recordings of the tests. commit 3f92f30afc5e932b2834a337401f51231abfb602 Author: Jiri Burant <[email protected]> Date: Mon Jun 7 17:39:44 2021 +0200 Renamed communication testcase and async communication testcase. commit 6f92a5aaf37c94878aedbfa4a505282e17041ff8 Author: Jiri Burant <[email protected]> Date: Mon Jun 7 17:25:47 2021 +0200 Fixed sanitized url to have .net instead of .com . commit 6e1ab5e228452b3bb29d9ec01b13a779cb6103c2 Author: Jiri Burant <[email protected]> Date: Mon Jun 7 17:25:04 2021 +0200 Fixed async client to have all the needed asynchronous behaviour commit a3ce07361fbab9f0fb335cd35379009486382786 Author: Jiri Burant <[email protected]> Date: Mon Jun 7 09:23:29 2021 +0200 Split the testcase and request replacer processor into two files. commit 26026c256bff0cd186f38656e0477f466e7e5d02 Author: Jiri Burant <[email protected]> Date: Mon Jun 7 08:18:44 2021 +0200 Modified paths to fake credential tokens to reflect teh changed naming. commit fdda1dd10f57b1f67a354fc844b8f5346d1ba200 Author: Jiri Burant <[email protected]> Date: Mon Jun 7 08:17:29 2021 +0200 Added dev requirement commit 2967dff8a91067cacdf34fb3047e5a992be1721b Author: Jiri Burant <[email protected]> Date: Mon Jun 7 08:17:10 2021 +0200 Renamed mocks to testcases commit 16b55c29ba7570d00e4ed1780f60da83e852258d Author: Jiri Burant <[email protected]> Date: Fri Jun 4 11:38:12 2021 +0200 Renamed variable names for sip configuration commit 63b338e3ea22e6a9c691e7a4f42663d03af5756c Author: Jiri Burant <[email protected]> Date: Fri Jun 4 10:45:37 2021 +0200 Renamed methods of sip routing client commit f709b26d646df3b9b98506af22185d800c02234a Author: Jiri Burant <[email protected]> Date: Fri Jun 4 10:20:49 2021 +0200 Modified clients to allow for credentials. commit ea8d1323fcfa069e066d52521a4f08f08dffe871 Author: Jiri Burant <[email protected]> Date: Fri Jun 4 10:14:02 2021 +0200 Initial Readms * Fixed readme links and formatting. Added sdk_moniker for client * Refactored authentication files. AAdded response sanitization. * Fixed linting issues. * Modified version to beta. * Regenerated swagger with latest definitions, implemented missing async sample files. * Fixing lint issues. * Fixed pylint disable comment. * Renamed sip routing client to match the conventions and updated tests. * Removed -Patch from public namespace. * Addressing comments from api review * Removed older files in separate package * Updated version for azure.core to support newly generated code. * Implemented swagger definition for SIP routing * Implemented SIP routing logic * Implemented siprouting changes * Added new types to public package * Changed phone numbers test to work with package structure * prepared recordings for sip routing * Added internal and public version of SipTrunk to accomodate for fqdn parameter. Changed public client interface to have functions separately for trunks/routes. * Fixing formatting. * Changed public interface. * Recordings of e2e tests. * Addressing comments from second internal review. * Minor changes in cleaning up code. Added a few sample calls. * Added test for token auth * Implemented inputs from api review * Fixed linting issues and credential issues. * Fixed test recordings. * Removed test credentials. * Moved siprouting tests to common namespace and removed packaging on tests. * Changed token authorization test to work in recorded mode. Fixed dependencies in setup.py file * Restored setup.py file to avoid package clashes. * Regenerated code with lower version of autorest to pass build validation. * Renamed replace_trunks and replace_routes to set_trunks, set_routes * Renamed recordings of tests. * Added more tests for managed identity. Updated README and Changelog. * Updated version. * Addressing comments from review. * Removing forgotten credential. * Addressing comments from review
1 parent 570cfb1 commit 7058612

File tree

76 files changed

+9632
-15
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+9632
-15
lines changed

sdk/communication/azure-communication-phonenumbers/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Release History
2+
## 1.1.0b3 (Unreleased)
3+
- Users can now manage SIP configuration for Direct routing.
4+
5+
### Features Added
6+
- Added new SIP routing client for handling Direct routing numbers.
27

38
## 1.1.0b2 (2022-03-30)
49

sdk/communication/azure-communication-phonenumbers/README.md

+104-13
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,18 @@ pip install azure-communication-phonenumbers
2020

2121
## Key concepts
2222

23-
### Initializing Phone Numbers Client
23+
This SDK provides functionality to easily manage `direct offer` and `direct routing` numbers.
24+
25+
The `direct offer` numbers come in two types: Geographic and Toll-Free. Geographic phone plans are phone plans associated with a location, whose phone numbers' area codes are associated with the area code of a geographic location. Toll-Free phone plans are phone plans not associated location. For example, in the US, toll-free numbers can come with area codes such as 800 or 888.
26+
They are managed using the `PhoneNumbersClient`
27+
28+
The `direct routing` feature enables connecting your existing telephony infrastructure to ACS.
29+
The configuration is managed using the `SipRoutingClient`, which provides methods for setting up SIP trunks and voice routing rules, in order to properly handle calls for your telephony subnet.
30+
31+
### Initializing Client
32+
Client can be initialized using the AAD authentication.
33+
2434
```python
25-
# You can find your connection string from your resource in the Azure Portal
2635
import os
2736
from azure.communication.phonenumbers import PhoneNumbersClient
2837
from azure.identity import DefaultAzureCredential
@@ -31,10 +40,20 @@ endpoint = "https://<RESOURCE_NAME>.communication.azure.com"
3140
# To use Azure Active Directory Authentication (DefaultAzureCredential) make sure to have your
3241
# AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET as env variables.
3342
phone_numbers_client = PhoneNumbersClient(endpoint, DefaultAzureCredential())
43+
```
3444

45+
```python
46+
import os
47+
from azure.communication.phonenumbers.siprouting import SipRoutingClient
48+
from azure.identity import DefaultAzureCredential
49+
50+
endpoint = "https://<RESOURCE_NAME>.communication.azure.com"
51+
# To use Azure Active Directory Authentication (DefaultAzureCredential) make sure to have your
52+
# AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET as env variables.
53+
sip_routing_client = SipRoutingClient(endpoint, DefaultAzureCredential())
3554
```
36-
### Initializing the Client Using Your Connection String
37-
Connection string authentication is also available for Phone Numbers Client.
55+
56+
Another option is to initialize the client using connection string of the resource.
3857

3958
```python
4059
# You can find your connection string from your resource in the Azure Portal
@@ -45,19 +64,39 @@ connection_str = "endpoint=ENDPOINT;accessKey=KEY"
4564
phone_numbers_client = PhoneNumbersClient.from_connection_string(connection_str)
4665
```
4766

48-
### Phone Number Types overview
67+
```python
68+
# You can find your connection string from your resource in the Azure Portal
69+
import os
70+
from azure.communication.phonenumbers.siprouting import SipRoutingClient
71+
72+
connection_str = "endpoint=ENDPOINT;accessKey=KEY"
73+
sip_routing_client = SipRoutingClient.from_connection_string(connection_str)
74+
```
75+
76+
### Phone numbers client
77+
78+
#### Phone number types overview
4979

5080
Phone numbers come in two types; Geographic and Toll-Free. Geographic phone numbers are phone numbers associated with a location, whose area codes are associated with the area code of a geographic location. Toll-Free phone numbers are phone numbers with no associated location. For example, in the US, toll-free numbers can come with area codes such as 800 or 888.
5181

52-
### Searching and Purchasing and Releasing numbers
82+
#### Searching and Purchasing and Releasing numbers
5383

5484
Phone numbers can be searched through the search creation API by providing an area code, quantity of phone numbers, application type, phone number type, and capabilities. The provided quantity of phone numbers will be reserved for ten minutes and can be purchased within this time. If the search is not purchased, the phone numbers will become available to others after ten minutes. If the search is purchased, then the phone numbers are acquired for the Azure resources.
5585

5686
Phone numbers can also be released using the release API.
5787

88+
### SIP routing client
89+
90+
Direct routing feature allows connecting customer-provided telephony infrastructure to Azure Communication Resources. In order to setup routing configuration properly, customer needs to supply the SIP trunk configuration and SIP routing rules for calls. SIP routing client provides the necessary interface for setting this configuration.
91+
92+
When the call arrives, system tries to match the destination number with regex number patterns of defined routes. The first route to match the number will be selected. The order of regex matching is the same as the order of routes in configuration, therefore the order of routes matters.
93+
Once a route is matched, the call is routed to the first trunk in the route's trunks list. If the trunk is not available, next trunk in the list is selected.
94+
5895
## Examples
5996

60-
### Get All Purchased Phone Numbers
97+
### PhoneNumbersClient
98+
99+
#### Get All Purchased Phone Numbers
61100

62101
Lists all of your purchased phone numbers
63102

@@ -67,7 +106,7 @@ for acquired_phone_number in purchased_phone_numbers:
67106
print(acquired_phone_number.phone_number)
68107
```
69108

70-
### Get Purchased Phone Number
109+
#### Get Purchased Phone Number
71110

72111
Gets the information from the specified phone number
73112

@@ -77,11 +116,11 @@ print(result.country_code)
77116
print(result.phone_number)
78117
```
79118

80-
## Long Running Operations
119+
### Long Running Operations
81120

82121
The Phone Number Client supports a variety of long running operations that allow indefinite polling time to the functions listed down below.
83122

84-
### Search for Available Phone Number
123+
#### Search for Available Phone Number
85124

86125
You can search for available phone numbers by providing the capabilities of the phone you want to acquire, the phone number type, the assignment type, and the country code. It's worth mentioning that for the toll-free phone number type, proving the area code is optional.
87126
The result of the search can then be used to purchase the number in the corresponding API.
@@ -103,7 +142,7 @@ poller = phone_numbers_client.begin_search_available_phone_numbers(
103142
search_result = poller.result()
104143
```
105144

106-
### Purchase Phone Numbers
145+
#### Purchase Phone Numbers
107146

108147
The result of your search can be used to purchase the specified phone numbers. This can be done by passing the `search_id` from the search response to the purchase phone number API.
109148

@@ -114,7 +153,7 @@ purchase_poller = phone_numbers_client.begin_purchase_phone_numbers(
114153
)
115154
```
116155

117-
### Release Phone Number
156+
#### Release Phone Number
118157

119158
Releases an acquired phone number.
120159

@@ -125,7 +164,7 @@ poller = self.phone_number_client.begin_release_phone_number(
125164
)
126165
```
127166

128-
### Updating Phone Number Capabilities
167+
#### Updating Phone Number Capabilities
129168

130169
Updates the specified phone number capabilities for Calling and SMS to one of:
131170

@@ -143,6 +182,58 @@ poller = self.phone_number_client.begin_update_phone_number_capabilities(
143182
)
144183
```
145184

185+
### SipRoutingClient
186+
187+
#### Retrieve SIP trunks and routes
188+
189+
Get the list of currently configured trunks or routes.
190+
191+
```python
192+
trunks = sip_routing_client.get_trunks()
193+
for trunk in trunks:
194+
print(trunk.fqdn)
195+
print(trunk.sip_signaling_port)
196+
routes = sip_routing_client.get_routes()
197+
for route in routes:
198+
print(route.name)
199+
print(route.description)
200+
print(route.number_pattern)
201+
for trunk_fqdn in route.trunks:
202+
print(trunk_fqdn)
203+
```
204+
205+
#### Replace SIP trunks and routes
206+
207+
Replace the list of currently configured trunks or routes with new values.
208+
209+
```python
210+
new_trunks = [SipTrunk(fqdn="sbs1.contoso.com", sip_signaling_port=1122), SipTrunk(fqdn="sbs2.contoso.com", sip_signaling_port=1123)]
211+
new_routes = [SipTrunkRoute(name="First rule", description="Handle numbers starting with '+123'", number_pattern="\+123[0-9]+", trunks=["sbs1.sipconfigtest.com"])]
212+
sip_routing_client.set_trunks(new_trunks)
213+
sip_routing_client.set_routes(new_routes)
214+
```
215+
216+
#### Retrieve single trunk
217+
218+
```python
219+
trunk = sip_routing_client.get_trunk("sbs1.contoso.com")
220+
```
221+
222+
#### Set single trunk
223+
224+
```python
225+
# Set function will either modify existing item or add new item to the collection.
226+
# The trunk is matched based on it's FQDN.
227+
new_trunk = SipTrunk(fqdn="sbs3.contoso.com", sip_signaling_port=5555)
228+
sip_routing_client.set_trunk(new_trunk)
229+
```
230+
231+
#### Delete single trunk
232+
233+
```python
234+
sip_routing_client.delete_trunk("sbs1.contoso.com")
235+
```
236+
146237
# Troubleshooting
147238
The Phone Numbers Administration client will raise exceptions defined in [Azure Core][azure_core].
148239

sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@
2626
'PhoneNumberAssignmentType',
2727
'PhoneNumberCapabilityType',
2828
'PhoneNumberType',
29-
'PhoneNumbersClient',
29+
'PhoneNumbersClient'
3030
]

sdk/communication/azure-communication-phonenumbers/azure/communication/phonenumbers/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
# license information.
55
# --------------------------------------------------------------------------
66

7-
VERSION = "1.1.0b2"
7+
VERSION = "1.1.0b3"
88

99
SDK_MONIKER = "communication-phonenumbers/{}".format(VERSION) # type: str
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# -------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for
4+
# license information.
5+
# --------------------------------------------------------------------------
6+
7+
8+
from ._sip_routing_client import SipRoutingClient
9+
from ._generated.models import SipTrunkRoute
10+
from ._models import SipTrunk
11+
12+
__all__ = [
13+
'SipRoutingClient',
14+
'SipTrunk',
15+
'SipTrunkRoute'
16+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for license information.
5+
# Code generated by Microsoft (R) AutoRest Code Generator.
6+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
7+
# --------------------------------------------------------------------------
8+
9+
from ._sip_routing_service import SIPRoutingService
10+
__all__ = ['SIPRoutingService']
11+
12+
# `._patch.py` is used for handwritten extensions to the generated code
13+
# Example: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
14+
from ._patch import patch_sdk
15+
patch_sdk()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for license information.
5+
# Code generated by Microsoft (R) AutoRest Code Generator.
6+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
7+
# --------------------------------------------------------------------------
8+
9+
from typing import TYPE_CHECKING
10+
11+
from azure.core.configuration import Configuration
12+
from azure.core.pipeline import policies
13+
14+
if TYPE_CHECKING:
15+
# pylint: disable=unused-import,ungrouped-imports
16+
from typing import Any
17+
18+
VERSION = "unknown"
19+
20+
class SIPRoutingServiceConfiguration(Configuration): # pylint: disable=too-many-instance-attributes
21+
"""Configuration for SIPRoutingService.
22+
23+
Note that all parameters used to create this instance are saved as instance
24+
attributes.
25+
26+
:param endpoint: The communication resource, for example
27+
https://resourcename.communication.azure.com.
28+
:type endpoint: str
29+
:keyword api_version: Api Version. Default value is "2021-05-01-preview". Note that overriding
30+
this default value may result in unsupported behavior.
31+
:paramtype api_version: str
32+
"""
33+
34+
def __init__(
35+
self,
36+
endpoint, # type: str
37+
**kwargs # type: Any
38+
):
39+
# type: (...) -> None
40+
super(SIPRoutingServiceConfiguration, self).__init__(**kwargs)
41+
api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: str
42+
43+
if endpoint is None:
44+
raise ValueError("Parameter 'endpoint' must not be None.")
45+
46+
self.endpoint = endpoint
47+
self.api_version = api_version
48+
kwargs.setdefault('sdk_moniker', 'siproutingservice/{}'.format(VERSION))
49+
self._configure(**kwargs)
50+
51+
def _configure(
52+
self,
53+
**kwargs # type: Any
54+
):
55+
# type: (...) -> None
56+
self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
57+
self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
58+
self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
59+
self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
60+
self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs)
61+
self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs)
62+
self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
63+
self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs)
64+
self.authentication_policy = kwargs.get('authentication_policy')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------
3+
#
4+
# Copyright (c) Microsoft Corporation. All rights reserved.
5+
#
6+
# The MIT License (MIT)
7+
#
8+
# Permission is hereby granted, free of charge, to any person obtaining a copy
9+
# of this software and associated documentation files (the ""Software""), to
10+
# deal in the Software without restriction, including without limitation the
11+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12+
# sell copies of the Software, and to permit persons to whom the Software is
13+
# furnished to do so, subject to the following conditions:
14+
#
15+
# The above copyright notice and this permission notice shall be included in
16+
# all copies or substantial portions of the Software.
17+
#
18+
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24+
# IN THE SOFTWARE.
25+
#
26+
# --------------------------------------------------------------------------
27+
28+
# This file is used for handwritten extensions to the generated code. Example:
29+
# https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
30+
def patch_sdk():
31+
pass

0 commit comments

Comments
 (0)