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

Adding SIP routing functionality to PhoneNumbers SDK #22805

Merged
merged 77 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
c54d87e
Initial commit
jiriburant May 25, 2021
c6bb58b
Copied shared files
jiriburant May 25, 2021
c6bdc1f
Added basic functionality to the sip client.
jiriburant May 25, 2021
33f5133
Copied shared folder to get the utilities. Implemented sample files. …
jiriburant May 26, 2021
8a5b5e3
Modified function comments and added class comment for _sip_routing_c…
jiriburant May 26, 2021
a929c00
Fixed kwargs propagation
jiriburant May 26, 2021
2d724f4
Changed sample file to pull parameteres from environment variables.
jiriburant May 26, 2021
4abde59
Changed get SIP configuration sample to be a class to align with the …
jiriburant May 26, 2021
9957f8e
Implemented basic tests for the SIP client
jiriburant May 28, 2021
91a5e1d
Removed unused import
jiriburant May 28, 2021
74a552c
Fixed comment.
jiriburant May 28, 2021
c72a481
Renamed variables dut_client to test_client.
jiriburant May 28, 2021
3a362d8
Added samples and tests of functionality.
jiriburant May 28, 2021
854cde6
Merge branch 'Azure:master' into feature/communication-sip-configuration
jiriburant May 28, 2021
0a97142
Merge from original repo
jiriburant May 28, 2021
76df991
Feature/communication sip configuration dev/basic client functionalit…
jiriburant May 31, 2021
95df4df
Updated from original (#4)
jiriburant May 31, 2021
a3b20fd
Merge branch 'Azure:master' into master
jiriburant May 31, 2021
6c6654b
Updated from upstream.
jiriburant May 31, 2021
5c6a037
Fixing pylint
jiriburant May 31, 2021
d1328d7
Changed value error to be compatible with python 2.
jiriburant May 31, 2021
00422ea
Reverted changes for pylint.
jiriburant May 31, 2021
f5263ba
Fixed dev requirements and MANIFEST
jiriburant May 31, 2021
f703cd9
Fixing async tests. Fixing comments.
jiriburant May 31, 2021
3e09e24
Removed async mock to be compatible with the builds.
jiriburant Jun 1, 2021
cf9256f
Fixing test failures for Ubuntu and Mac
jiriburant Jun 1, 2021
ffda58d
Changed versions for python. Fixed pylint issue in version.
jiriburant Jun 1, 2021
ff9c526
Modified _version file to prevent path errors.
jiriburant Jun 2, 2021
591bcdd
Added newline.
jiriburant Jun 2, 2021
03f5064
Downgraded six version to match the frozen requirements.
jiriburant Jun 2, 2021
14a48f5
Fixed async test errors by excluding asynchronous tests for python 2.7.
jiriburant Jun 2, 2021
5f8fc23
Regenerated by autorest
jiriburant Jun 3, 2021
216208f
Updated swagger definition.
jiriburant Jun 3, 2021
f73900e
Squashed commit of the following:
jiriburant Jun 7, 2021
026649b
Fixed readme links and formatting. Added sdk_moniker for client
jiriburant Jun 7, 2021
1e51336
Refactored authentication files. AAdded response sanitization.
jiriburant Jun 8, 2021
6a2fc1a
Fixed linting issues.
jiriburant Jun 8, 2021
e8b9322
Modified version to beta.
jiriburant Jun 8, 2021
9336ab1
Regenerated swagger with latest definitions, implemented missing asyn…
jiriburant Jun 10, 2021
3dbbb5e
Fixing lint issues.
jiriburant Jun 10, 2021
81c6f3f
Fixed pylint disable comment.
jiriburant Jun 11, 2021
46ab396
Renamed sip routing client to match the conventions and updated tests.
jiriburant Jun 15, 2021
d8922b8
Removed -Patch from public namespace.
jiriburant Sep 13, 2021
1e4f62c
Addressing comments from api review
jiriburant Jan 14, 2022
bee5c36
Removed older files in separate package
jiriburant Jan 27, 2022
5dd3f4c
Updated version for azure.core to support newly generated code.
jiriburant Jan 27, 2022
9d17a46
Implemented swagger definition for SIP routing
jiriburant Jan 27, 2022
ce00bad
Implemented SIP routing logic
jiriburant Jan 27, 2022
f1413f0
Implemented siprouting changes
jiriburant Jan 27, 2022
34807f2
Added new types to public package
jiriburant Jan 27, 2022
cf958ea
Changed phone numbers test to work with package structure
jiriburant Jan 27, 2022
1846f92
prepared recordings for sip routing
jiriburant Jan 27, 2022
0eb018e
Added internal and public version of SipTrunk to accomodate for fqdn …
jiriburant Feb 9, 2022
dec049a
Fixing formatting.
jiriburant Feb 16, 2022
d38c191
Changed public interface.
jiriburant Feb 16, 2022
b4678f5
Recordings of e2e tests.
jiriburant Feb 16, 2022
2349f1a
Addressing comments from second internal review.
jiriburant Mar 4, 2022
dc74c1e
Minor changes in cleaning up code. Added a few sample calls.
jiriburant Mar 9, 2022
012ad16
Merge branch 'Azure:main' into master
jiriburant Mar 9, 2022
29b148f
Added test for token auth
jiriburant Apr 13, 2022
e4e1d60
Merge branch 'Azure:main' into master
jiriburant Apr 21, 2022
9176da9
Implemented inputs from api review
jiriburant Apr 21, 2022
eaf4682
Merged from master
jiriburant Apr 21, 2022
5d3fd57
Fixed linting issues and credential issues.
jiriburant Apr 21, 2022
0a422f2
Fixed test recordings.
jiriburant Apr 21, 2022
d157a4f
Removed test credentials.
jiriburant Apr 21, 2022
ed60fe9
Moved siprouting tests to common namespace and removed packaging on t…
jiriburant Apr 22, 2022
0b176d7
Changed token authorization test to work in recorded mode.
jiriburant Apr 22, 2022
ec0b2ec
Restored setup.py file to avoid package clashes.
jiriburant Apr 22, 2022
8252f24
Regenerated code with lower version of autorest to pass build validat…
jiriburant Apr 22, 2022
79d9fc6
Renamed replace_trunks and replace_routes to set_trunks, set_routes
jiriburant May 10, 2022
0aaab75
Renamed recordings of tests.
jiriburant May 20, 2022
d1ad44a
Added more tests for managed identity. Updated README and Changelog.
jiriburant May 24, 2022
9736c52
Updated version.
jiriburant May 24, 2022
e44036d
Addressing comments from review.
jiriburant Jun 7, 2022
a68fbb8
Removing forgotten credential.
jiriburant Jun 7, 2022
daf47c8
Addressing comments from review
jiriburant Jun 9, 2022
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Release History
## 1.1.0b3 (Unreleased)
- Users can now manage SIP configuration for Direct routing.

### Features Added
- Added new SIP routing client for handling Direct routing numbers.

## 1.1.0b2 (2022-03-30)

Expand Down
117 changes: 104 additions & 13 deletions sdk/communication/azure-communication-phonenumbers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,18 @@ pip install azure-communication-phonenumbers

## Key concepts

### Initializing Phone Numbers Client
This SDK provides functionality to easily manage `direct offer` and `direct routing` numbers.

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.
They are managed using the `PhoneNumbersClient`

The `direct routing` feature enables connecting your existing telephony infrastructure to ACS.
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.

### Initializing Client
Client can be initialized using the AAD authentication.

```python
# You can find your connection string from your resource in the Azure Portal
import os
from azure.communication.phonenumbers import PhoneNumbersClient
from azure.identity import DefaultAzureCredential
Expand All @@ -31,10 +40,20 @@ endpoint = "https://<RESOURCE_NAME>.communication.azure.com"
# To use Azure Active Directory Authentication (DefaultAzureCredential) make sure to have your
# AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET as env variables.
phone_numbers_client = PhoneNumbersClient(endpoint, DefaultAzureCredential())
```

```python
import os
from azure.communication.phonenumbers.siprouting import SipRoutingClient
from azure.identity import DefaultAzureCredential

endpoint = "https://<RESOURCE_NAME>.communication.azure.com"
# To use Azure Active Directory Authentication (DefaultAzureCredential) make sure to have your
# AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET as env variables.
sip_routing_client = SipRoutingClient(endpoint, DefaultAzureCredential())
```
### Initializing the Client Using Your Connection String
Connection string authentication is also available for Phone Numbers Client.

Another option is to initialize the client using connection string of the resource.

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

### Phone Number Types overview
```python
# You can find your connection string from your resource in the Azure Portal
import os
from azure.communication.phonenumbers.siprouting import SipRoutingClient

connection_str = "endpoint=ENDPOINT;accessKey=KEY"
sip_routing_client = SipRoutingClient.from_connection_string(connection_str)
```

### Phone numbers client

#### Phone number types overview

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.

### Searching and Purchasing and Releasing numbers
#### Searching and Purchasing and Releasing numbers

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.

Phone numbers can also be released using the release API.

### SIP routing client

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.

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.
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.

## Examples

### Get All Purchased Phone Numbers
### PhoneNumbersClient

#### Get All Purchased Phone Numbers

Lists all of your purchased phone numbers

Expand All @@ -67,7 +106,7 @@ for acquired_phone_number in purchased_phone_numbers:
print(acquired_phone_number.phone_number)
```

### Get Purchased Phone Number
#### Get Purchased Phone Number

Gets the information from the specified phone number

Expand All @@ -77,11 +116,11 @@ print(result.country_code)
print(result.phone_number)
```

## Long Running Operations
### Long Running Operations

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

### Search for Available Phone Number
#### Search for Available Phone Number

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.
The result of the search can then be used to purchase the number in the corresponding API.
Expand All @@ -103,7 +142,7 @@ poller = phone_numbers_client.begin_search_available_phone_numbers(
search_result = poller.result()
```

### Purchase Phone Numbers
#### Purchase Phone Numbers

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.

Expand All @@ -114,7 +153,7 @@ purchase_poller = phone_numbers_client.begin_purchase_phone_numbers(
)
```

### Release Phone Number
#### Release Phone Number

Releases an acquired phone number.

Expand All @@ -125,7 +164,7 @@ poller = self.phone_number_client.begin_release_phone_number(
)
```

### Updating Phone Number Capabilities
#### Updating Phone Number Capabilities

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

Expand All @@ -143,6 +182,58 @@ poller = self.phone_number_client.begin_update_phone_number_capabilities(
)
```

### SipRoutingClient

#### Retrieve SIP trunks and routes

Get the list of currently configured trunks or routes.

```python
trunks = sip_routing_client.get_trunks()
for trunk in trunks:
print(trunk.fqdn)
print(trunk.sip_signaling_port)
routes = sip_routing_client.get_routes()
annatisch marked this conversation as resolved.
Show resolved Hide resolved
for route in routes:
print(route.name)
print(route.description)
print(route.number_pattern)
for trunk_fqdn in route.trunks:
print(trunk_fqdn)
```

#### Replace SIP trunks and routes

Replace the list of currently configured trunks or routes with new values.

```python
new_trunks = [SipTrunk(fqdn="sbs1.contoso.com", sip_signaling_port=1122), SipTrunk(fqdn="sbs2.contoso.com", sip_signaling_port=1123)]
new_routes = [SipTrunkRoute(name="First rule", description="Handle numbers starting with '+123'", number_pattern="\+123[0-9]+", trunks=["sbs1.sipconfigtest.com"])]
sip_routing_client.set_trunks(new_trunks)
sip_routing_client.set_routes(new_routes)
```

#### Retrieve single trunk

```python
trunk = sip_routing_client.get_trunk("sbs1.contoso.com")
```

#### Set single trunk

```python
# Set function will either modify existing item or add new item to the collection.
# The trunk is matched based on it's FQDN.
new_trunk = SipTrunk(fqdn="sbs3.contoso.com", sip_signaling_port=5555)
sip_routing_client.set_trunk(new_trunk)
```

#### Delete single trunk

```python
sip_routing_client.delete_trunk("sbs1.contoso.com")
```

# Troubleshooting
The Phone Numbers Administration client will raise exceptions defined in [Azure Core][azure_core].

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
'PhoneNumberAssignmentType',
'PhoneNumberCapabilityType',
'PhoneNumberType',
'PhoneNumbersClient',
'PhoneNumbersClient'
]
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
# license information.
# --------------------------------------------------------------------------

VERSION = "1.1.0b2"
VERSION = "1.1.0b3"

SDK_MONIKER = "communication-phonenumbers/{}".format(VERSION) # type: str
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------


from ._sip_routing_client import SipRoutingClient
from ._generated.models import SipTrunkRoute
from ._models import SipTrunk

__all__ = [
'SipRoutingClient',
'SipTrunk',
'SipTrunkRoute'
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from ._sip_routing_service import SIPRoutingService
__all__ = ['SIPRoutingService']

# `._patch.py` is used for handwritten extensions to the generated code
# Example: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
from ._patch import patch_sdk
patch_sdk()
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from typing import TYPE_CHECKING

from azure.core.configuration import Configuration
from azure.core.pipeline import policies

if TYPE_CHECKING:
# pylint: disable=unused-import,ungrouped-imports
from typing import Any

VERSION = "unknown"

class SIPRoutingServiceConfiguration(Configuration): # pylint: disable=too-many-instance-attributes
"""Configuration for SIPRoutingService.

Note that all parameters used to create this instance are saved as instance
attributes.

:param endpoint: The communication resource, for example
https://resourcename.communication.azure.com.
:type endpoint: str
:keyword api_version: Api Version. Default value is "2021-05-01-preview". Note that overriding
this default value may result in unsupported behavior.
:paramtype api_version: str
"""

def __init__(
self,
endpoint, # type: str
**kwargs # type: Any
):
# type: (...) -> None
super(SIPRoutingServiceConfiguration, self).__init__(**kwargs)
api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: str

if endpoint is None:
raise ValueError("Parameter 'endpoint' must not be None.")

self.endpoint = endpoint
self.api_version = api_version
kwargs.setdefault('sdk_moniker', 'siproutingservice/{}'.format(VERSION))
self._configure(**kwargs)

def _configure(
self,
**kwargs # type: Any
):
# type: (...) -> None
self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs)
self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs)
self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs)
self.authentication_policy = kwargs.get('authentication_policy')
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# coding=utf-8
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------

# This file is used for handwritten extensions to the generated code. Example:
# https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
def patch_sdk():
pass
Loading