6 июл. 2008 г.

Модель разработки телекоммуникационных сервисов с использованием IP PBX Asterisk.

Хотелось бы поделиться с Вами работой, в которой рассмотрена интересная, на мой взгляд, модель использования PBX Asterisk. Если быть более точным, то идея заключается в использовании Asterisk в качестве платформы разработки телекоммуникационных сервисов. Обладая открытым исходным кодом и API, Asterisk позволяет свести разработку телекоммуникационных сервисов к веб-программированию, что резко снижает входной барьер для программиста, создающего новые сервисы.
В данной работе предлагается расширить Asterisk новым компонентом (прокси), основной функцией которого является перевод телекоммуникационных вызовов в HTTP запросы к внешним веб-сервисам. При этом телекоммуникационные сервисы располагаются отдельно от PBX, а информацию от Asterisk в виде HTTP-запроса. Технически - это HTTP GET/POST запрос, в котором внешнему телекоммуникационному сервису передается информация об имени абонента - CallerIdName, номере вызывающего абонента - CallerIdNumber и номере вызываемого абонента - Extension. Исходя из полученных параметров (номер вызывающего/вызываемого абонента) веб-сервис формирует ответные инструкции, которые получает прокси и транслирует в команды Asterisk. Разработка сервисов в такой архитектуре выглядит как создание обычного CGI-скрипта, для написания которого имеется не мало средств разработки. В результате программист освобождается от изучения API Asterisk.
Рассмотрим более подробно модель разработки телекоммуникационных сервисов. На схеме показана общая архитектура решения.

На данной схеме центральное место занимает AGI-proxy, который представляет из себя Java-приложение, реализованное на базе открытой библиотеки FastAGI. AGI-proxy устанавливается непосредственно на стороне PBX Asterisk.
По сути, Asterisk является тем же для AGI-proxy, что и J2EE контейнер для сервлета. Все вызовы от Asterisk приходят в прокси в метод service с двумя параметрами: интерфейсы AgiRequest и AgiChannel. Через первый параметр можно получить информацию о вызове (имя/номер вызывающего абонента, номер вызываемого абонента, контекст вызова, параметры канала и т.д.), а через второй – осуществлять взаимодействие с Asterisk (прекращение вызова, перевод в режим ответа и т.д.). AGI-proxy "заворачивает" в строку имя абонента - CallerIdName, номер вызывающего - CallerIdNumber, номер вызываемого абонента - Extension и от своего имени выполняет HTTP запрос к некоторму веб-сервису, URL которого настроен при конфигурации. Ответ сервиса рассматривается как указание на то, что дальше делать со звонком, например, звонок можно терминировать, проиграть позвонившему медиа-файл, можно переадресовать звонок на указанный номер. Инструкции, которые возвращает внешний сервис должны быть в xml-формате, схема которого очень проста:

Пример типичного отклика веб-сервиса:

Получив данный xml-ответ, прокси проиграет медиа-файл (playMadiaFile) с названием «demo-nogo».
В такой архитектуре последовательность вызовов сводится к очень простой диаграмме, отдельные шаги которой упоминались выше.

Хотелось бы несколько слов сказать о внешних веб-сервисах и привести упрощенный пример. Веб-сервисы в такой модели могут преследовать самые разные цели – от статистических (отметить факт звонка и завершить его - в системах голосования) до задач управления планами маршрутизации Asterisk (автоответчики и переадресация в информационных системах).
Для демонстрации работоспособности модели прокси представлен двумя файлами agiproxy.jar, AgiProxyScript.java и парой файлов конфигурации - agiproxy.conf, fastagi-mapping.properties. Необходимо скопировать их в /var/lib/asterisk/agi-bin/ и выполнить следующие шаги для настройки прокси:

1. Настроить extensions (вызовы), на которые будет «реагировать» прокси: в файле /etc/asterisk/extensions.conf прописать, например такую строку:
exten => _1XXX,1,Agi(agi://localhost/proxy.agi)
(прокси запуститься при наборе четырехзначного номера, начинающегося с «1»)

2. Настроить URL внешнего сервиса (см.далее), с которым прокси будет взаимодействовать. В файле /var/lib/asterisk/agi-bin/agiproxy.conf добавить, например, строку:
urltunnel=http://localhost:8080/agiweb/agi.jsp
(выполнять HTTP-запрос к agi.jsp на localhost)

3. Настроить параметры для взаимодействия прокси с Asterisk в файле /var/lib/asterisk/agi-bin/agiproxy.conf:
hostname=localhost (имя сервера Asterisk)
username=manager (имя пользователя из файла manager.conf)
password=pa55w0rd (пароль из файла manager.conf)

4. Скомпилировать AgiProxyScript.java для вашей операционной системы следующим образом: из /var/lib/asterisk/agi-bin/ выполнить команду (для java версии 1.6):
javac -cp .:asterisk-java-0.3.1.jar:agiproxy.jar AgiProxyScript.java

5. Запустить Asterisk, например командой:
asterisk -vvvvvcd

6. Запустить AgiServer выполнив из /var/lib/asterisk/agi-bin/ команду
java -cp agiproxy.jar:asterisk-java-0.3.1.jar:. org.asteriskjava.fastagi.DefaultAgiServer

В качестве внешнего сервиса была написана тривиальная java server page (agi.jsp), которая сначала разбирает строку параметров от AGI-proxy и определяет вызываемый номер (Extension), а затем по этому номеру формирует инструкции для Asterisk: для номера 1200 будет проигран медиа-файл, вызов номера 1300 будет переадресован на номер 500, а все остальные звонки терминированы.
В заключении напомню преимущества использования данной модели разработки телекоммуникационных сервисов по сравнению с традиционным «программированием» диалплана в файлах конфигурации:


1. Снижается входной барьер для программиста, создающего новые телекоммуникационные сервисы.
2. Возможность разработки сервисов с использованием различных средств – CGI, JSP, ASP.NET.
3. Возможность добавления внешних сервисов без каких-либо изменений на стороне PBX.

Статья не претендует на революционность идеи, а представленные пример на богатый функционал. Это всего лишь попытка создать некоторую базу для Open Source проекта, направленного на развитие средств разработки для Asterisk.

Исходный код прокси и файлы для установки примера доступны здесь.

Текст статьи на английском языке.


4 комментария:

Анонимный комментирует...

Ну, наконец-то нашел жтвой пример использования asterisk-java!!! Андрей, можно попросить Вас написать статью(-и) о самом концептуальном подходе разработки приложени, используя asterisk-java. Или,если такие существуют, забугорные источники (кроме собственно немногословного aster-java.org) в которых даются пояснения "с нуля". Заранее благодарен за ответ. C уважением Андрей

Андрей Устинов комментирует...

Добрый день, Андрей.
Рад, что статья Вам стала интересна.
Хотел сначала было описать подход asterisk-java в виде комментария на Вашу просьбу, но в конце концов решил оформить это заметкой. Сегодня-завтра я её выложу в блоге.

Анонимный комментирует...

Очень неплохая статья. Андрей, можно попросить Вас повторно выложить файлы. За ранее благодарен. С уважением Максим.

openfor комментирует...

Спасибо, Максим. Все ссылки в статье обновлены, пример доступен для скачивания.