<div dir="ltr">Matt,<div><br></div><div>  I think your entire email should be put on the wiki, maybe not in its current format, but the contents are imperative<br>for the future. This is actually the first ever detailed explanation I've ever read as to why ARI shouldn't do all sorts<br>of things - which from an external (none core developer) point of view - would seem reasonable. </div><div><br></div><div>   <br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 18, 2014 at 8:38 PM, Matthew Jordan <span dir="ltr"><<a href="mailto:mjordan@digium.com" target="_blank">mjordan@digium.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div class="h5"><br><br>On Thu, Dec 18, 2014 at 10:31 AM, Leif Madsen <<a href="mailto:lmadsen@thinkingphones.com" target="_blank">lmadsen@thinkingphones.com</a>> wrote:<br>> On 18 December 2014 at 11:07, Paul Belanger <<a href="mailto:paul.belanger@polybeacon.com" target="_blank">paul.belanger@polybeacon.com</a>><br>> wrote:<br>>><br>>> On Thu, Dec 18, 2014 at 1:59 AM, Nir Simionovich<br>>> <<a href="mailto:nir.simionovich@gmail.com" target="_blank">nir.simionovich@gmail.com</a>> wrote:<br>>> > New question: Do we want to enable legacy features inside ARI?<br>>> ><br>>> New answer: I don't believe so.<br>>><br>>> I think this issue / question is the hardest thing to understand about<br>>> ARI.  There really isn't any sort of link to existing Asterisk<br>>> application or features; not yet any ways.  Somebody has to build it<br>>> again a top of ARI.<br>>><br>>> When I first dreamed of using ARI I was looking at it from a<br>>> configuration management tool mindset.  Oh, I could create a new peer<br>>> in chan_sip over HTTP or let me reconfigure features.conf using ARI.<br>>> However, as I started playing with it more I found that was not what<br>>> it did.  And, changing it to do something like that doesn't feel like<br>>> the right approach.<br>>><br>>> Now, that being said. Creating some sort of interface to control<br>>> sorcery objects, now that would be cool.  Having sorcery connect to<br>>> redis and change key / values directly in redis for sip peers would be<br>>> hotness.  However, I'm not sure I would want to have Asterisk serve up<br>>> that interface directly.  Feels more like an external application<br>>> would serve up the REST interface into redis, allowing the user to<br>>> change key/pairs.<br>>><br>>> I also believe, until there are some standard ARI libraries /<br>>> application (for example app_dial replacement). It will feel like a<br>>> large task to build anything in ARI, because some of the core<br>>> application basically need to be written from scratch.  And I think<br>>> this is the main reason people are slow to move to ARI or fearful from<br>>> dropping the dialplan.  Because doing:<br>>><br>>> exten => s,1,NoOp()<br>>>     same => n,Dial(SIP/<a href="mailto:foo@example.org" target="_blank">foo@example.org</a>)<br>>><br>>> is a lot easier then origination a channel over ARI, creating bridges<br>>> and playing any tones needed using ARI.  Easier might not be the right<br>>> work, more steps required is.<br>><br>><br>> I also agree that we do not want to start making ARI start talking to legacy<br>> applications.<br>><br>> As discussed at AstriDevCon, the push is really to start making Asterisk a<br>> media communications platform. The way to do that is to move away from the<br>> dialplan centric driven applications and to move to a decentralized model of<br>> applications and business logic being separated from Asterisk, and<br>> essentially making Asterisk much dumber in terms of the actual business<br>> logic and routing logic, and making it a lean mean media communications<br>> machine. The way forward sometimes is to stop looking back.<br>><br>> Currently both AMI and AGI are still happily co-existant in Asterisk, and<br>> should be considered the defacto interface to traditional methods of writing<br>> Asterisk business logic (dialplan, etc). When flipping to ARI, it is a<br>> different mind set that does take some time to get around. Much like Paul I<br>> had my own preconceived notions about what ARI was and was initially<br>> disappointed it didn't match what I thought it should have been. However<br>> over the last few months of watching what Paul has been doing along with<br>> some small side POC stuff to better understand what ARI is intended for, it<br>> definitely has become a lot clearer.<br>><br>> At the most basic levels, ARI to me is a bridge control interface that<br>> allows you to hook channels together while not worrying about transcoding,<br>> media characteristics etc. You have two or more channels that may or may not<br>> speak the same language, and your external applications stick them together,<br>> and Asterisk acts as the universal translator for those channels. By writing<br>> all your business logic and controls outside of Asterisk, it makes the API<br>> much simpler to interoperate with, and allows great scaling possibilities.<br>><br>> Admittedly I'm still a bit naive on a lot of the ARI front, but one thing my<br>> gut tells me, is it is a new interface, and should not be confused as a<br>> replacement to the legacy (term used loosely) methods of building Asterisk<br>> systems. This is one of those situations that I feel avoiding legacy and<br>> backwards compatibility with the traditional methods is going to really open<br>> up a better realm of possibilities with ARI. If someone truly just needs an<br>> HTTP based interface for controlling dialplan and such, I feel a translation<br>> application (library) should just be written for AMI and AGI that permits<br>> that and has that goal. Overloading what ARI is supposed to be doing is a<br>> step backwards in my opinion.<br><br></div></div>Exposing Asterisk features (and that term encompasses 'features.conf' features as well as other things) in the short run would add more features to the API, but in the long run will result in severely limiting the ARI API - and making it really difficult to build ARI applications. I think everyone is on this page from this thread, but for the sake of posterity, I'll go into some of where this would fall apart if we tried to put 'features' into ARI.<br><br>Integral to ARI is the concept of control. When a channel is in your Stasis dialplan application, *you* own the channel. Asterisk has handed it over to your external application to control. When a channel is not in a Stasis application, your ARI application can be aware of the channel's existence, but it does *not* own the channel - Asterisk does. And Asterisk will do crazy complicated things to channels when it owns them (re: masquerades, media manipulations, lots of swapping between bridges, local channel optimizations, etc.) These operations are safe when Asterisk manipulates them, but cannot be made safe to all ARI operations - initiating a /play operation on a channel in the middle of an existing media operation would be "interesting". Taking a Local channel that is half-way through an optimization and pushing it into a bridge would be a "bad thing". This hard distinction is what makes ARI safe: because we *know* that a channel in Stasis is owned by an external application, we can make assumptions about what Asterisk can and cannot do to the channel. The reverse is also true: when Asterisk controls a channel, we can make assumptions about what the ARI API will let an external application do to a channel.<br><br>Having a safe border makes both worlds happier. "Good fences make good neighbours".<br><br>So, let's see where this breaks down with features. Say I wanted to have Asterisk features attended transfers in ARI. I'd want some 'flag' passed in when I add a channel to a bridge that says "yes, this channel can perform an attended transfer". Maybe something like this:<br><br>POST /bridges/bridge-12345/addChannel?channel=channel-1&feature=atxfer<br><br>Er... except, how does Asterisk know what DTMF sequence triggers the attended transfer feature? I could rely on features.conf, but that's a poor solution that falls afoul of scalability and multi-tenancy. I could just require people to use FEATURE_MAP on the channel prior to adding it to the bridge, which isn't too bad.<br><br>POST /channels/channel-1/variable?variable=FEATURE_MAP(atxfer)&value=1<br>POST /bridges/bridge-12345/addChannel?channel=channel-1&feature=atxfer<br><br>Okay, so that's not so bad. Yay! I have attended transfers! Let's see where this starts to break down:<br><br>My ARI application controls bridge-12345 and added channel-1 to it. Let's say my ARI application also had a channel-2 that was added to the bridge:<br><br>POST /bridges/bridge-12345/addChannel?channel=channel-2<br><br>So channel-1 initially talks to channel-2, and then decides to perform a features attended transfer of channel-2 to someone else. When channel-1 hits '1' and starts the features attended transfer code, channel-1 will get placed into a bridge created by Asterisk and a Local channel will be created to go execute the dialplan extension that they enter. The bridge and Local channel created as part of this is not controlled by my ARI application; nor is the resulting execution of the dialplan at that location: the core features code in Asterisk is working with the dialplan, and goes to execute dialplan at that location.<br><br>Let's assume that the dialplan location that is the target of the attended transfer performs a Dial operation, creating an outbound channel we'll call channel-3. channel-3 is Answered, and a new bridge is formed between the Local channel that executed dialplan and channel-3. Again, this is not under the control of my ARI application; all of these channels are controlled by Asterisk. Through Local channel optimization, channel-1 and channel-3 will end up in the same bridge - neither of which is controlled by ARI.<br><br>To recap:<br> * We have had a Local channel be created and destroyed (via optimization) that was not part of my ARI application<br> * We have a new channel, channel-3, that is now talking to channel-1 - but that I have no control over<br> * We have an existing channel, channel-1, which ostensibly has now left my application but is the channel I used to control<br> * We have had two bridges be created that I had no control over, one of which is now destroyed<br><br>All of which my ARI application however would generally want to be aware of - as I still have channel-2 waiting in my ARI application bridge that I may need to do something with.<br><br>Now things get really difficult to track and understand in the ARI application:<br>(1) If the attended transfer completes successfully, then either channel-2 will be moved into channel-3's bridge (that I don't control), or channel-3 will be moved into channel-2's bridge (that I do control). In this particular case, channel-3 comes in "through the back door" into the ARI application, while in the other case, channel-2 will leave "through the back door" (this does work after some recent bug fixing). Regardless, there are cases where an ARI application will have to understand that it will get channels handed to it that it didn't expect, and cases where channels will leave its application that it didn't expect.<br>(2) If channel-1 toggles between channel-2 and channel-3's bridges, there will be race conditions in the controlling of channel-1: when it is in the bridge with channel-2, ARI can control it; when it enters the bridge it shares with channel-3, ARI can't control it. Since a human being is mashing these buttons, you will have races where ARI thinks it can control channel-1, but by the time the request reaches Asterisk, Asterisk will have already moved it into a bridge with channel-3 and the request will fail.<br>(3) If the attended transfer is converged into a 3-way, then we'll have the same situation as (1) but now with more channels. Again, we may lose control of channel-2, while at the same time re-gaining control of channel-1 and gaining control of channel-3.<br></div><div><br></div><div>None of this sounds easy for an ARI application to keep track of. The answer here is *not* to allow ARI control things that Asterisk is controlling: the number of race conditions, unsafe behaviours, and crashes that would encounter is mind-boggling. I really can't predict how poorly that would go, other than to say I would not want to try and maintain Asterisk any longer :-)<br><br>There's a reason the only thing you can really do that truly alters the state of a channel in AMI is Redirect - and that's not a trivial operation to get right all the time internally.<br><br>What's more, what if I didn't want Asterisk's attended transfer behaviour? What if I wanted channel-1 to only be able to perform attended transfers to their supervisor - a much more likely scenario for call centers. This would be nice, as for my application, I could bypass the need for the initiator to 'dial an extension' - they could just hit 1 and have the whole process kick off! Doing this would be extremely non-trivial in Asterisk, and nearly impossible to do in a generic fashion. However, this is not especially difficult to implement in JavaScript, Python, or any other language that ARI lends itself to.<br><br></div><div>The point of all this is: Asterisk limits you. When you rely on its internal mechanisms and constructs, yes, you don't have to write any code - but you can only tweak it as far as it lets you go. ARI presents the building blocks of Asterisk and lets you go build whatever you want with it. While you can mix the worlds to an extent using the Stasis dialplan application - which is a good thing - mixing the world owned by Stasis and the world owned by the Asterisk core is fraught with peril: both for Asterisk developers and for those attempting to build applications with ARI.<br></div><div><br></div><div>Matt<span class="HOEnZb"><font color="#888888"><br></font></span></div><span class="HOEnZb"><font color="#888888"><div><br>-- <br>Matthew Jordan<br>Digium, Inc. | Engineering Manager<br>445 Jan Davis Drive NW - Huntsville, AL 35806 - USA<br>Check us out at: <a href="http://digium.com" target="_blank">http://digium.com</a> & <a href="http://asterisk.org" target="_blank">http://asterisk.org</a></div></font></span></div></div></div></div></div>
<br>--<br>
_____________________________________________________________________<br>
-- Bandwidth and Colocation Provided by <a href="http://www.api-digital.com" target="_blank">http://www.api-digital.com</a> --<br>
<br>
asterisk-dev mailing list<br>
To UNSUBSCRIBE or update options visit:<br>
   <a href="http://lists.digium.com/mailman/listinfo/asterisk-dev" target="_blank">http://lists.digium.com/mailman/listinfo/asterisk-dev</a><br></blockquote></div></div>