17 Application Selection And Composition Model
17.8 Popping of Top Route Header
17.8.1 Container Behavior
With application composition the requirement of popping the top route header belonging to the container [as described in 6.6.3 Popped Route Header ] is to be done on receipt of request not just on the network interface from external SIP entity but also within the container when the request is received from one of the applications. This will happen when one of the applications pushes a route header that happens to belong to the container. This popping of container's route can happen irrespective of the request being initial or subsequent. Besides this the Application Router can also modify the route header originally popped on initial request processing as per 17.3 Application Router Behavior.
17.8.2 Top Route Processing Examples
This section contains three examples to help illustrate the behavior of route popping, Application Router, SipServletRequest.getPoppedRoute() as well as the
SipServletRequest.getInitialPoppedRoute() API methods.
17.8.2.1 Request with two route headers arriving at the container
This example illustrates an application chain with two applications (App1, App2), where neither application pushes routes onto the incoming request.(Alice) - AR - App1 - AR - App2 - AR - (Bob)
1. Request R from Alice arrives at the container.
2. The request contains two route headers, A_i and B_e. A_i represents a route pointing to the container, B_e means it is an external route. The AR receives the request R.
3. Inside of the AR, R.getPoppedRoute() returns A_i as A_i is popped by the container prior to passing the request onto the AR. Also, R.getInitialPoppedRoute() returns A_i. R still contains B_e route header. The AR returns App1, and NO_ROUTE modifier to the container. 4. App1 executes.
5. Inside of App1, R.getPoppedRoute() returns A_i and R's top route is B_e.
R.getInitialPoppedRoute() returns A_i. App1 proxies request to Bob, without calling pushRoute().
6. The AR intercepts the request again.
7. Inside of the AR, R.getPoppedRoute() returns null and R still contains B_e as its top route. R.getInitialPoppedRoute() still returns A_i. AR returns App2 and NO_ROUTE modifier to the container.
8. App2 executes.
9. In App2, R.getPoppedRoute() returns null, and R's top route is B_e.
R.getInitialPoppedRoute() returns A_i. App2 proxies R to R's Request-URI (Bob). The AR executes.
AR returns null application to the container, and NO_ROUTE. This causes the container to send the request to B_e, as per 17.4.1 Procedure for Routing an Initial Request, point 3.
17.8.2.2 Application pushes route pointing back at the container
This example illustrates container behavior when the application pushes a route onto the incoming request pointing back to the container.(Alice) - AR - App1 - AR - (Bob)
1. Request R from Alice arrives at the container.
2. The request contains two route headers, A_i and B_e. A_i represents a route pointing to the container, B_e means it is an external route. The AR receives the request R.
P o p p i n g o f T o p R o u t e H e a d e r
3. Inside of the AR, R.getPoppedRoute() returns A_i as A_i is popped by the container prior to passing the request onto the AR. R.getInitialPoppedRoute() returns A_i. R still contains B_e route header. The AR returns App1, and NO_ROUTE modifier to the container. 4. App1 executes.
5. Inside of App1, R.getPoppedRoute() returns A_i and R's top route is B_e.
R.getInitialPoppedRoute() returns A_i. App1 calls R.pushRoute(C_i), where C_i represents a Route header pointing back at the container. Next, App1 proxies the request to Bob. The AR intercepts the request again.
Inside of the AR, R.getPoppedRoute() returns C_i, and R's top route header is B_e. R.getInitialPoppedRoute() returns A_i. AR decides to return null application to the container, and NO_ROUTE. This causes the container to send the request to B_e, as per
17.4.1 Procedure for Routing an Initial Request, point 3.
17.8.2.3 Application pushes external route
This example illustrates container behavior when an application pushes an external route. (Alice) - AR - App1 - AR - (Bob)
1. Request R from Alice arrives at the container.
2. The request contains two Route headers, A_i and B_e. A_i represents a Route pointing to the container, B_e means it is an external Route. The AR receives the request R.
3. Inside of the AR, R.getPoppedRoute() returns A_i as A_i is popped by the container prior to passing the request onto the AR. R.getInitialPoppedRoute() returns A_i. R still contains B_e Route header. The AR returns App1, and NO_ROUTE modifier to the container. 4. App1 executes.
5. Inside of App1, R.getPoppedRoute() returns A_i and R's top route is B_e.
R.getInitialPoppedRoute() returns A_i. App1 calls R.pushRoute(D_e), where D_e represents a Route header pointing to an external address. Next, App1 proxies the request to Bob. The AR intercepts the request again.
Inside of the AR, R.getPoppedRoute() returns null, and R's top route header is D_e. R.getInitialPoppedRoute() returns A_i. AR decides to return null application to the container, and NO_ROUTE. This causes the container to send the request to D_e, as per
17.9 Examples
The first example uses a simple two applications scenario to illustrate the interactions between container, Application Router and applications along with the concept of application path and routing of subsequent requests and responses. It also serves to illustrate the concept of message context discussed in 7.4.1 Message Context. The examples that follow the first examine more complex application composition scenarios.
17.9.1 Example with Two Applications
Consider the Location Service (LS) application in 1.6.1 A Location Service, and a new Speed-Dial (SD) application. This latter application allows a calling party to specify a short speed-dial number (e.g. "1"), which it translates into a complete address based on prior
configuration. LS allows the called party to control where calls are received. For the purpose of illustration, assume that both SD and LS applications record-route.
The following diagram shows the routing of an initial INVITE request. Assuming that the caller and callee of the INVITE request are both subscribers served by this server, SD is needed to serve the caller and LS is needed to serve the callee. The following step-by-step walkthrough of the call flow indicates message context as a triplet (app, as, ss) where app is the application name, as specifies an application session, and ss specifies a SipSession.
Example of Application Composition:
---> SD ---> LS --->
1. The container receives an INVITE request. The INVITE does not belong to an existing SIP dialog and so the container calls the Application Router with the request to obtain the name of the application to invoke.
2. The Application Router determines SD is the first application to serve the caller. The Application Router returns the name "SD", the caller's identity, and the originating region to the container together with some state information.
3. The container invokes the SD application in the context of (SD, as1, ss1).
4. SD, based on the caller's identity, performs database lookup to obtain the caller's speed-dial settings and proxies to the full address that corresponds to the speed-dial number.
5. The container receives the proxied request and again calls the Application Router with the request and the state information.
E x a m p l e s
6. Based on the state information, the Application Router determines that SD has already been invoked and there are no other applications for the caller. Assuming that there are no applications in the neutral region, the Application Router proceeds to the terminating region and determines that LS is needed to service the callee. It returns the name "LS", the callee's identity, and the terminating region to the container, together with some state information. 7. The container invokes the LS application in the context of (LS, as2, ss2).
8. LS, based on the callee's identity, performs database lookup to obtain the callee's location settings and proxies the request to destination d1.
9. The container receives the proxied request and calls the Application Router with the request and state information.
10. The Application Router determines that no applications are required for d1, and returns null to the container indicating there is no further application to be invoked.
11. The container proxies the request towards d1, that is, outside the application server. 12. The container receives a 200 (OK) response for the INVITE. The 200 response is passed
upstream along the reverse path of the request, i.e. the container passes it first to the LS application in context (LS, as2, ss2) and then to the SD application in context (SD, as1, ss1), and then sends it to the caller.
13. Since the 200 response establishes a dialog, an application path is created. This means that the container will route subsequent requests in this dialog to applications along the signaling path. In this case the application path consists of (SD, as1, as2) and (LS, as2, ss2).
14. An ACK for the 200 is received. This is recognized as being a subsequent request and is associated with the previously established application path. (Incoming ACKs for non-2xx final responses are needed for protocol reasons only and are simply dropped.)
15. The container passes the ACK to the SD application in the context (SD, as1, ss1) and when the upcall to SD returns, it passes the ACK to the LS application in the context (LS, as2, ss2). When the upcall to LS returns, the container proxies the ACK outside the application server according to standard SIP routing rules.
16. Assuming that the callee hangs up first, the BYE is passed along the application path in the reverse direction, i.e. it is passed to LS first, then SD.
Note that, logically, each application has its own set of SIP client and server transaction objects operating in accordance with the transaction state machines specified in the SIP specification [RFC 3261, chapter 17]. Likewise, logically, each proxy application executes its own instance of the proxy logic, for example, it has its own response context [RFC 3261, section 16]. This
specification then "augments" the RFC 3261 defined state machines with additional rules, for example, that 100 responses, ACKs for non-2xx responses, and responses for CANCELs are not delivered to the applications.
17.9.2 Simple call with no modifications of
requests
As an example, assume that Alice, Bob, and Carol all subscribe to the following applications: z Originating region applications:
– Originating call screening (OCS) z Terminating region applications:
– Call Forwarding (CF) – Incoming Call Logging (ICL)
z Applications in both originating and terminating regions: – Call Waiting (CW)
– 3-Way Calling (3WC)
Assume that all these applications proxy or relay the initial requests they receive without modification. Also assume that the Application Router selects applications based on a simple ordering: the originating applications in the order CW, 3WC, OCS and the terminating applications in the order ICL, CF, 3WC, CW.
When the container receives a call from Alice to Bob, it calls the Application Router which selects CW to service Alice, because CW is the first application in Alice's originating region. When CW relays the INVITE as a B2BUA, the container again calls the Application Router. Because the application selection process is carried forward from the INVITE that CW received to the INVITE that CW is now sending, the Application Router determines that CW has already been invoked based on the current state of the selection process and that the next application is therefore 3WC. The same process is repeated when 3WC relays the INVITE request and the OCS application is invoked next. When OCS relays the INVITE request, the Application Router determines that there are no more originating applications for Alice. The application selection process then proceeds to the callee’s i.e., Bob's terminating region, where ICL, CF, 3WC and CW are then invoked in turn. During this call, we assume that CF, although present, is not active. That is, it does not forward the call to another URI. When Bob's CW relays the INVITE, there are no more terminating applications for Bob and thus the container sends the request to Bob's UA.