Package com.ericsson.ssa.sip

Source Code of com.ericsson.ssa.sip.SessionTarget

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Parameterable Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Parameterable, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ericsson.ssa.sip;

import java.util.Iterator;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.sip.ServletParseException;
import javax.servlet.sip.ar.SipTargetedRequestInfo;
import org.jvnet.glassfish.comms.util.LogUtil;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.enterprise.server.ApplicationServer;
import javax.servlet.sip.Parameterable;

/**
* Base class for Join and Replace handling. This class holds the code for
* basic error handling of the request with Join or Replace header. It also
* find the session/application of the original request.
*
* @author binod
*/
public abstract class SessionTarget {

    protected Parameterable target = null;
    private String callId = null;
    private String fromTag = null;
    private String toTag = null;
    private String fragmentId = null;
    private SipApplicationSessionImpl sas = null;
    private SipSessionImplBase ss = null;
    private static final Logger logger = LogUtil.SIP_LOGGER.getLogger();
    protected static final LocalStringManagerImpl localStrings =
            new LocalStringManagerImpl(SipSessionImplBase.class);

    /**
     * Creates the Session Target.
     * @param target Join or Replace Header
     */
    protected SessionTarget(Parameterable target) {
        this.target = target;
    }

    /**
     * Set the CallId, from and to tags of the original request that is being
     * targetted.
     *
     * @param callId
     * @param fromTag
     * @param toTag
     */
    protected void setParams(String callId, String fromTag, String toTag, String fid) {
        this.callId = callId;
        this.fromTag = fromTag;
        this.toTag = toTag;
        this.fragmentId = fid;
    }

    /**
     * Setup activity. It validates, header, find the dialog, sesion
     * and application session.
     *
     * @param req
     * @throws com.ericsson.ssa.sip.SessionTargetException
     */
    public static void setup(SipServletRequestImpl req)
    throws SessionTargetException {
        ListIterator<Parameterable> lit;

        Parameterable join = null;
        Parameterable replaces = null;
       
        try {
            lit = (ListIterator<Parameterable>)
            req.getParameterableHeaders(Header.JOIN);
        } catch (ServletParseException ex) {
            if (logger.isLoggable(Level.WARNING)) {
                logger.log(Level.WARNING, ex.getLocalizedMessage(), ex);
            }
            String msg = localStrings.getLocalString(
            "errr_reading_join", "Error parsing Join header.");
            throw new SessionTargetException(400, msg);
        }
       
        if (lit.hasNext()) {
            join = lit.next();
            if (lit.hasNext()) {               
                String msg = localStrings.getLocalString(
                "morethan_one_join","More than one Join or Replace Header");               
                throw new SessionTargetException(400, msg);
            }
        }
        try {

            lit =
            (ListIterator<Parameterable>) req.getParameterableHeaders(Header.REPLACES);
        } catch (ServletParseException ex) {
            String msg = localStrings.getLocalString(
            "errr_reading_replaces", "Error parsing Replaces header.");
            throw new SessionTargetException(400, msg);
        }
       
        if (lit.hasNext()) {
            if (join != null) {
                String msg = localStrings.getLocalString(
                "morethan_one_join","More than one Join or Replace Header");
                throw new SessionTargetException(400, msg);
            }
            replaces = (ParameterableImpl) lit.next();
            if (lit.hasNext()) {
                String msg = localStrings.getLocalString(
                "morethan_one_join","More than one Join or Replace Header");
                throw new SessionTargetException(400, msg);
            }
        }

        SessionTarget st = null;
        if (join != null) {
            st = new JoinHandler(join);
        } else if (replaces != null) {
            st = new ReplacesHandler(replaces);
        } else {
            if (logger.isLoggable(Level.FINE)) {
                logger.log(Level.FINE, "There is no Join or Replace header");
            }
            return;
        }

        if (!req.getMethod().equals("INVITE")) {
            String msg = localStrings.getLocalString(
            "jr_on_noninvite",
            "Join and Replace headers can be used only for INVITE requests.");
            throw new SessionTargetException(400, msg);
        }

        st.init();
        try {
            if (st.saveApplicationSession()) {
                st.terminateOriginalRequest();
                req.setSessionTarget(st);
            }
        } catch (RemoteLockException ex) {  
            if (logger.isLoggable(Level.WARNING)) {
                logger.log(Level.WARNING, ex.getLocalizedMessage(), ex);
            }
            String msg = localStrings.getLocalString(
            "unknown_error_jr","Unknown error during Join/Replace handling");
            throw new SessionTargetException(500, "");
        }
               
        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "Join/Replace is setup now.");
        }
    }

    /**   
     * @return the application session for this join/replace.
     */
    public SipApplicationSessionImpl getApplicationSessionImpl() {
        return this.sas;
    }
   
    /**    
     * @return the session of the original or targetted request.
     */
    public SipSessionImplBase getSessionImpl() {
        return this.ss;
    }
   
    //Well, since JOIN and Replace really are initial requests, fid wouldnt
    //be there..
    private String computeFragmentId(int i) {
        return  ApplicationServer.getServerContext().getInstanceName() + "_" + i;
    }

    /**
     * Find the dialog, session and application session.
     *
     * @throws com.ericsson.ssa.sip.SessionTargetException
     * @throws com.ericsson.ssa.sip.RemoteLockException
     */
    boolean saveApplicationSession()
    throws SessionTargetException, RemoteLockException {
        String fid = fragmentId;
        DialogFragment d = null;


        for (int i = 1; i < 11; i++) {
            if (fragmentId == null) {
                fid = computeFragmentId(i);
            }
       
            String id = DialogFragment.createKey(callId, toTag, fromTag, fid);

            d = DialogFragmentManager.getInstance().findDialogFragment(id);

            if (logger.isLoggable(Level.FINE)) {
                logger.fine("Dialog using key " + id + " is :" + d);
            }

            if (d != null || fragmentId != null) {
                break;
            }
        }

        validateDialogFragment(d);
       
        PathNode p = null;
        if (d != null && d.isValid()) {
            Iterator<PathNode> iter = null;
            if (fromTag.equals(d.getFromTag())) {
                iter = d.getCallee2CallerPath();
            } else {
                iter = d.getCaller2CalleePath();
            }

            while (iter.hasNext()) {
               p = iter.next();                   
            }
        }
       
        if (p != null) {
            if (! p.getType().equals(PathNode.Type.Proxy)) {
                SipSessionBase ss = p.getSipSession();
                if (ss.isValid()) {
                    this.sas = ss.getApplicationSessionImpl();
                    this.ss = (SipSessionImplBase) ss;
                    if (logger.isLoggable(Level.FINE)) {
                        logger.fine("Found the original dialog/session/sas"
                        +" for Join/Replace");
                    }
                    return true;
                }
            } else {
                //JSR 289 mandate that we only search UAs for
                //the Join/Replace session. So, if a session of a proxy
                //matches, most likely, the request should be forwarded.
                //No session targetting in this container.               
                return false;
            }
        }   
         String msg = localStrings.getLocalString(
         "no_session_jr","Could not find session for Join or Replace");
        throw new SessionTargetException(481,msg);
    }

   
    /**
     * Return the header name.
     *
     * @return "Join" or "Replaces"
     */
    public abstract String getHeader();

    /**
     * Return the Target request info for the targetted app.
     *
     * @return SipTargetedRequestInfo for Application Router.
     */
    public abstract SipTargetedRequestInfo getTargetedRequestInfo();
   
    /**
     * Initialises the Join or Replace Handler.
     */
    abstract void init();
   
    /**
     * It may be debated that the original request need to be terminated.
     * This is a place holder for the functionality. Noop for now.
     */
    abstract void terminateOriginalRequest()
    throws SessionTargetException;   
   
    /**
     * Validate the DialogFragment of the original/targetted dialog.
     */
    protected void validateDialogFragment(DialogFragment d)
    throws SessionTargetException {
        if (d != null && ! d.isValid()) {
            String msg = localStrings.getLocalString(
            "session_notvalid_jr","Terminated session for Join or Replace");
            throw new SessionTargetException(603, msg);
        }
    }
}
TOP

Related Classes of com.ericsson.ssa.sip.SessionTarget

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.