В последнее время на хабре появилось довольно много статей, посвященных астериску и во всех статьях авторы для описания dial plan'а используют стандартный extensions.conf. Я не буду описывать здесь формат записи в extensions.conf, а лишь постараюсь кратко описать его различия с конфигурационными файлами в формате AEL(extensions.ael), которых на самом деле совсем немного, а вот удобств ael добавляет значительно. В дальнейшем, для удобства, dial plan, описанный в extensions.conf буду называть «обычным» форматом, ну а ael — соответственно ael. Давайте рассмотрим пример простейшего dial plan'a в обычном формате:
;
А вот так этот же контекст будет выглядеть в синтаксисе ael:
Итак, различия налицо. Для меня одним из главных плюсов ael является удобство чтения конфига: даже на этом маленьком абстрактном примере видно, что читать и понимать конфиг проще. Хотя, допускаю, что это субъективно. Второе что сразу бросается в глаза — это отсутствие приоритета (s,n в коде выше, правда, как заметили в комментариях, приоритет и там уже не обязателен) в описании dialplan'a.
Почему их нет? Вернее, почему они есть в описании обычного dialplan'a?
Если вы не имели до этого дела с астериском и с его обычным dialplan'ом, то вы будете удивлены, узнав что в нем нет ни циклов, ни условий. Есть только лишь условный переход (gotoif), с помощью которого, в принципе, можно организовать даже циклы, но удобство этого подхода весьма сомнительно. Давайте представим себе простейший ael код, который будет выводить в консоль астериска true или false:
В обычном виде это условие будет выглядеть так:
Мало того, что мы потеряли «читаемость», так еще и вынуждены либо статически прописывать везде приоритеты (и получить абсолютно нерасширяемый код), либо придумывать метки на каждый чих. Да, в ael тоже есть метки, только надобность в них практически пропадает, так как синтаксис позволяет уйти от goto как такового.
Кроме непосредственно условий (if/else) в ael вы можете использовать и оператор switch с привычным синтаксисом:
А теперь попробуйте описать эту же конфигурацию, но в обычном формате? То то же.
А теперь представьте себе, что у вас более-менее сложный dialplan, который со временем будет расти и расширяться, будет добавляться новый функционал, будет много условий, очередей и так далее — здесь без ael все будет довольно печально. По работе периодически приходится настраивать астериск и запросы у клиентов бывают довольно экзотичными. Решать эти задачи без ael было бы гораздо сложнее.
Справедливости ради следует сказать, что астериск преобразует конфигурацию ael в «обычный» формат и работает уже с ним (можно проверить через asterisk -rx «dialplan show»), так что его синтаксис тоже знать обязательно. Но ael может значительно облегчить жизнь, тем более, как вы видите, синтаксис у него довольно очевиден, а если есть опыт написания обычных dial plan'ов, то перейти на ael будет легко.
;
[internal] exten => s,1,Answer exten => s,n,Background(someivr) exten => s,n,Read(intgroup,,3) exten => s,n,Goto(${intgroup},1) exten => XXX,1,Dial(SIP/${EXTEN}) exten => XXX,n,HangUp
А вот так этот же контекст будет выглядеть в синтаксисе ael:
context internal { s=> { Answer; Background(someivr); Read(intgroup,,3); Goto(${intgroup},1); } XXX => { Dial(SIP/${EXTEN}); HangUp; } }
Итак, различия налицо. Для меня одним из главных плюсов ael является удобство чтения конфига: даже на этом маленьком абстрактном примере видно, что читать и понимать конфиг проще. Хотя, допускаю, что это субъективно. Второе что сразу бросается в глаза — это отсутствие приоритета (s,n в коде выше, правда, как заметили в комментариях, приоритет и там уже не обязателен) в описании dialplan'a.
Почему их нет? Вернее, почему они есть в описании обычного dialplan'a?
Если вы не имели до этого дела с астериском и с его обычным dialplan'ом, то вы будете удивлены, узнав что в нем нет ни циклов, ни условий. Есть только лишь условный переход (gotoif), с помощью которого, в принципе, можно организовать даже циклы, но удобство этого подхода весьма сомнительно. Давайте представим себе простейший ael код, который будет выводить в консоль астериска true или false:
if(${var}=foo) { NoOp(true); } else { NoOp(false); }
В обычном виде это условие будет выглядеть так:
exten=>1,1,GotoIf($[${var}=foo]?label1:label2) exten=>1,n(label1),NoOp(true) exten=>1,n,Goto(end_of_if) exten=>1,n(label2),NoOp(false) exten=>1,n(end_of_if),...
Мало того, что мы потеряли «читаемость», так еще и вынуждены либо статически прописывать везде приоритеты (и получить абсолютно нерасширяемый код), либо придумывать метки на каждый чих. Да, в ael тоже есть метки, только надобность в них практически пропадает, так как синтаксис позволяет уйти от goto как такового.
s=> { Answer; somelabel: HangUp; }
Кроме непосредственно условий (if/else) в ael вы можете использовать и оператор switch с привычным синтаксисом:
_777X => { switch (${EXTEN}) { pattern N11: NoOp(You called a N11 number-- ${EXTEN}); break; case 7771: NoOp(You called 7771!); break; case 7772: NoOp(You called 7772!); break; case 7773: NoOp(You called 7773!); // fall thru- default: NoOp(In the default clause!); };
А теперь попробуйте описать эту же конфигурацию, но в обычном формате? То то же.
А теперь представьте себе, что у вас более-менее сложный dialplan, который со временем будет расти и расширяться, будет добавляться новый функционал, будет много условий, очередей и так далее — здесь без ael все будет довольно печально. По работе периодически приходится настраивать астериск и запросы у клиентов бывают довольно экзотичными. Решать эти задачи без ael было бы гораздо сложнее.
Справедливости ради следует сказать, что астериск преобразует конфигурацию ael в «обычный» формат и работает уже с ним (можно проверить через asterisk -rx «dialplan show»), так что его синтаксис тоже знать обязательно. Но ael может значительно облегчить жизнь, тем более, как вы видите, синтаксис у него довольно очевиден, а если есть опыт написания обычных dial plan'ов, то перейти на ael будет легко.