Package org.cipango.server.handler

Source Code of org.cipango.server.handler.SipContextHandlerCollection

// ========================================================================
// Copyright 2008-2009 NEXCOM Systems
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================

package org.cipango.server.handler;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.sip.Address;
import javax.servlet.sip.ServletParseException;
import javax.servlet.sip.SipServletMessage;
import javax.servlet.sip.SipServletResponse;
import javax.servlet.sip.SipURI;
import javax.servlet.sip.ar.SipApplicationRouterInfo;
import javax.servlet.sip.ar.SipApplicationRoutingDirective;
import javax.servlet.sip.ar.SipRouteModifier;

import org.cipango.server.ConnectorManager;
import org.cipango.server.ID;
import org.cipango.server.Server;
import org.cipango.server.SipConnector;
import org.cipango.server.SipHandler;
import org.cipango.server.SipMessage;
import org.cipango.server.SipRequest;
import org.cipango.server.SipResponse;
import org.cipango.server.ar.RouterInfoUtil;
import org.cipango.server.session.CallSessionHandler;
import org.cipango.server.session.SipSessionHandler;
import org.cipango.server.transaction.TransactionManager;
import org.cipango.sip.NameAddr;
import org.cipango.sip.SipParams;
import org.cipango.sip.SipURIImpl;
import org.cipango.sip.URIFactory;
import org.cipango.sipapp.SipAppContext;
import org.cipango.util.ExceptionUtil;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;

/**
* Handler responsible for application selection based on application router result. In addition, it also
* performs session key targeting when needed.
*
* It extends the HTTP {@link ContextHandlerCollection}. However, contrary to HTTP, the selected handler
* is not invoked directly for processing since several handlers necessary to SIP Servlets are invoked first.
* Therefore, selected application handler is stored in the request for use at a later stage.
*/
public class SipContextHandlerCollection extends ContextHandlerCollection implements SipHandler
    private SipAppContext[] _sipContexts;
    private SipHandler _handler;
   
  public SipContextHandlerCollection()
    {
    super();
    setContextClass(SipAppContext.class);
  }
 
  @Override
  protected void doStart() throws Exception
  {
    if (_handler == null)
    {
      CallSessionHandler callSessionHandler = new CallSessionHandler();
      SipSessionHandler sipSessionHandler = new SipSessionHandler();
     
      TransactionManager transactionManager = ((Server) getServer()).getTransactionManager();
      callSessionHandler.setHandler(transactionManager);
     
      transactionManager.setHandler(sipSessionHandler);
     
      _handler = callSessionHandler;
    }

    _handler.setServer(getServer());
   
    if (_handler instanceof LifeCycle)
      ((LifeCycle) _handler).start();
    super.doStart();
  }
 
   public void setHandler(SipHandler handler)
   {
     _handler = handler;
   }
 
  public SipAppContext[] getSipContexts()
  {
    return _sipContexts;
  }
 
  public SipAppContext getContext(String name)
  {
    if (_sipContexts != null)
    {
      for (int i = 0; i < _sipContexts.length; i++)
      {
        if (_sipContexts[i].getName().equals(name)) 
          return _sipContexts[i];
      }
    }
    return null;
  }
 
  @Override
    public void setHandlers(Handler[] handlers)
    {
      super.setHandlers(handlers);
       
        Object sipHandlers = null;
        if (handlers != null)
        {
            for (int i = 0; i < handlers.length; i++)
            {
                if (handlers[i] instanceof SipAppContext)
                    sipHandlers = LazyList.add(sipHandlers, handlers[i]);
            }
        }
        _sipContexts = (SipAppContext[]) LazyList.toArray(sipHandlers, SipAppContext.class);
    }

  public ConnectorManager getConnectorManager()
  {
    return ((Server) getServer()).getConnectorManager();
  }
 
  private boolean isInitial(SipRequest request)
  {
    return ((request.getTo().getParameter(SipParams.TAG) == null) && !request.isCancel());
  }
 
  public Address popLocalRoute(SipRequest request)
  {
    Address route = request.getTopRoute();
    if (route != null && getConnectorManager().isLocalUri(route.getURI()))
    {
      request.removeTopRoute();
      return route;
    }
    return null;
  }
 
  public void handle(SipServletMessage message) throws ServletException, IOException
    {
    if (((SipMessage) message).isRequest())
    {
      SipRequest request = (SipRequest) message;
   
      Address route = popLocalRoute(request);
     
      if (isInitial(request))
          {
        request.setInitial(true);
       
        SipApplicationRouterInfo routerInfo = null;
        SipAppContext appContext = null;
       
        try
        {
          if (route != null)
          {
            SipURI uri = (SipURI) route.getURI();
            if (RouterInfoUtil.ROUTER_INFO.equals(uri.getUser()))
            {
              routerInfo = RouterInfoUtil.decode(uri);
              route = popLocalRoute(request);
            }
            if (route != null)
              request.setPoppedRoute(route);
          }
         
          if (routerInfo == null)
          {
            routerInfo = ((Server) getServer()).getApplicationRouter().getNextApplication(
              request, null, SipApplicationRoutingDirective.NEW, null, null);
          }
        }
        catch (Throwable t)
        {
          if (!request.isAck())
          {
            SipResponse response = new SipResponse(
                request,
                SipServletResponse.SC_SERVER_INTERNAL_ERROR,
                "Application router error: " + t.getMessage());
            ExceptionUtil.fillStackTrace(response, t);
            getConnectorManager().sendResponse(response);
          }
          return;
        }
       
        if (routerInfo != null && routerInfo.getNextApplicationName() != null)
        {
          boolean handle = handlingRoute(request, routerInfo);
          if (handle)
            return;
         
          request.setStateInfo(routerInfo.getStateInfo());
          request.setRegion(routerInfo.getRoutingRegion());
         
          String s = routerInfo.getSubscriberURI();
          if (s != null)
          {
            try
            {
              request.setSubscriberURI(URIFactory.parseURI(s));
            }
            catch (ServletParseException e)
            {
              Log.debug(e);
            }
          }
         
          String applicationName = routerInfo.getNextApplicationName();
          appContext = (SipAppContext) getContext(applicationName);
                   
          Method method = appContext == null ? null : appContext.getSipApplicationKeyMethod();
          if (method != null)
          {
            try
            {
              String sessionKey = (String) method.invoke(null, request);
             
              if (Log.isDebugEnabled())
                Log.debug("routing initial request to key {}", sessionKey);
             
              request.addHandlerAttribute(ID.SESSION_KEY_ATTRIBUTE, sessionKey);
            }
            catch (Exception e)
            {
              Log.debug("failed to get SipApplicationKey", e);
            }
          }
         
          if (Log.isDebugEnabled())
            Log.debug("application router returned application {} for initial request {}", applicationName, request.getMethod());
          if (appContext == null && applicationName != null)
            Log.debug("No application with name {} returned by application router could be found", applicationName, null);
        }
       
        if (appContext == null)
        {
         
          if (!request.isAck())
          {
            SipResponse response = new SipResponse(request, SipServletResponse.SC_NOT_FOUND, null);
            response.to().setParameter(SipParams.TAG, ID.newTag());
            getConnectorManager().sendResponse(response);
          }
          return;
        }     
        request.addHandlerAttribute(ID.CONTEXT_ATTRIBUTE, appContext);
      }
      else
      {
        if (route != null)
          request.setPoppedRoute(route);
      }
    }   
    _handler.handle(message);
    }
 
  private boolean handlingRoute(SipRequest request, SipApplicationRouterInfo routerInfo)
  {
    if (routerInfo.getRouteModifier() == null || SipRouteModifier.NO_ROUTE == routerInfo.getRouteModifier())
      return false;
   
    String[] routes = routerInfo.getRoutes();
    try
    {
      if (SipRouteModifier.ROUTE == routerInfo.getRouteModifier() && routes != null)
      {
        Address topRoute = new NameAddr(routes[0]);
        if (getConnectorManager().isLocalUri(topRoute.getURI()))
          request.setPoppedRoute(topRoute);
        else
        {
          for (int i = routes.length; i >= 0; --i)
            request.pushRoute(new NameAddr(routes[i]));
          request.send();
          return true;
        }
      }
      else if (SipRouteModifier.ROUTE_BACK == routerInfo.getRouteModifier() && routes != null)
      {
        SipConnector defaultConnector = getConnectorManager().getDefaultConnector();
          SipURI ownRoute = new SipURIImpl(null, defaultConnector.getHost(), defaultConnector.getPort());
          RouterInfoUtil.encode(ownRoute, routerInfo);

          ownRoute.setLrParam(true);
        request.pushRoute(ownRoute);
        for (int i = routes.length; i >= 0; --i)
          request.pushRoute(new NameAddr(routes[i]));
        request.send();
        return true;
      }
      else if (routes == null
          && (SipRouteModifier.ROUTE_BACK == routerInfo.getRouteModifier() || SipRouteModifier.ROUTE == routerInfo.getRouteModifier()))
      {
        Log.debug("Router info set route modifier to {} but no route provided, assume NO_ROUTE", routerInfo.getRouteModifier());
      }
      return false;
    }
    catch (Exception e)
    {
      if (!request.isAck())
      {
        // Could have ServletParseException or IllegalArgumentException on pushRoute
        SipResponse response = (SipResponse) request.createResponse(
                SipServletResponse.SC_SERVER_INTERNAL_ERROR,
                "Error in handler: " + e.getMessage());
        ExceptionUtil.fillStackTrace(response, e);
        try { getConnectorManager().sendResponse(response); } catch (Exception e1) {Log.ignore(e1); }
      }
          return true;
    }
  }
}
TOP

Related Classes of org.cipango.server.handler.SipContextHandlerCollection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.