Package com.ericsson.ssa.config

Source Code of com.ericsson.ssa.config.SipFactoryFacade

/*
* 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 Header 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
* Header, 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.config;

import com.ericsson.ssa.sip.RemoteLockException;
import com.ericsson.ssa.sip.RemoteLockRuntimeException;
import com.ericsson.ssa.sip.SipApplicationSessionImpl;
import com.ericsson.ssa.sip.SipApplicationSessionUtil;
import com.ericsson.ssa.sip.SipFactoryImpl;
import com.ericsson.ssa.sip.SipServletRequestImpl;
import com.ericsson.ssa.sip.SipSessionManager;
import com.ericsson.ssa.sip.URIImpl;
import com.ericsson.ssa.sip.UriUtil;
import com.ericsson.ssa.utils.UUIDUtil;
import com.ericsson.ssa.container.sim.InvocationContextUtil;

import org.jvnet.glassfish.comms.deployment.backend.SipApplication;
import org.jvnet.glassfish.comms.deployment.backend.SipApplicationListeners;
import org.jvnet.glassfish.comms.security.auth.impl.AuthInfoImpl;
import org.jvnet.glassfish.comms.util.LogUtil;

import java.io.UnsupportedEncodingException;

import java.lang.reflect.Method;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.sip.Address;
import javax.servlet.sip.AuthInfo;
import javax.servlet.sip.Parameterable;
import javax.servlet.sip.ServletParseException;
import javax.servlet.sip.SipApplicationSession;
import javax.servlet.sip.SipFactory;
import javax.servlet.sip.SipServletRequest;
import javax.servlet.sip.SipURI;
import javax.servlet.sip.URI;


/**
* Facade for the SipFactoryImpl singelton.
*
* A new instance of SipFactoryFacade is bound to each context, with key
* "javax.servlet.sip.SipFactory"
*
* @author lmcpepe
*/
public class SipFactoryFacade implements SipFactory {
    private static final Logger logger = LogUtil.SIP_LOGGER.getLogger();
    private ConvergedContext m_Ctx;
    private String m_ApplicationName;
    private SipFactoryImpl m_ConcreteSipFactory;
    private SipApplication m_SipApplication;
    private SipSessionManager m_SipSessionManager;

    //
    private Method sessionKey = null;

    /**
     * @param sipApplication
     */
    public SipFactoryFacade(ConvergedContext ctx, SipFactoryImpl sipfactory, SipApplication sipApplication) {
        m_Ctx = ctx;
        m_ApplicationName = ctx.getAppName();
        m_SipSessionManager = ctx.getSipSessionManager();
        m_ConcreteSipFactory = sipfactory;
        m_SipApplication = sipApplication;
    }

    /**
     * Constructor called from startup to bind a Referece to a new facade in JNDI.
     * A default Facade is provided to @Resource annotated SipFactory in Java EE components
     *
     * To create an Application Session on a default Facade, the method
     *  createApplicationSessionByAppname(String appName) has to be used.
     *
     */
    public SipFactoryFacade() {
        m_ConcreteSipFactory = SipFactoryImpl.getInstance();
    }

    /**
     * Set context specific data for a Facade, this configures the Facad to be context avare
     *
     * @param ctx
     * @param sipApplication
     */
    public void setContextData(ConvergedContext ctx, SipApplication sipApplication) {
        m_Ctx = ctx;
        m_ApplicationName = ctx.getAppName();
        m_SipSessionManager = ctx.getSipSessionManager();
        m_SipApplication = sipApplication;
    }

    public SipURI createSipURI(String user, String host) {
        return m_ConcreteSipFactory.createSipURI(user, host);
    }

    public URI createURI(String uri) throws ServletParseException {
        return m_ConcreteSipFactory.createURI(uri);
    }

    public Address createAddress(String address) throws ServletParseException {
        return m_ConcreteSipFactory.createAddress(address);
    }

    public Address createAddress(URI uri) {
        return m_ConcreteSipFactory.createAddress(uri);
    }

    public Address createAddress(URI uri, String string) {
        return m_ConcreteSipFactory.createAddress(uri, string);
    }

    public Parameterable createParameterable(String s) throws ServletParseException {
        return m_ConcreteSipFactory.createParameterable(s);
    }

    public SipServletRequest createRequest(SipApplicationSession appSession, String method, Address from, Address to) {
        SipServletRequestImpl request = m_ConcreteSipFactory.createRequest(appSession, method, from, to);
        postCreateRequest(request);

        return request;
    }

    public SipServletRequest createRequest(SipApplicationSession appSession, String method, URI from, URI to) {
        SipServletRequestImpl request = m_ConcreteSipFactory.createRequest(appSession, method, from, to);
        postCreateRequest(request);

        return request;
    }

    public SipServletRequest createRequest(SipApplicationSession appSession, String method, String from, String to) throws ServletParseException {
        SipServletRequestImpl request = m_ConcreteSipFactory.createRequest(appSession, method, from, to);
        postCreateRequest(request);

        return request;
    }

    @Deprecated
    public SipServletRequest createRequest(SipServletRequest origRequest, boolean sameCallId) {
        SipServletRequestImpl request = m_ConcreteSipFactory.createRequest(origRequest, sameCallId);
        postCreateRequest(request);

        return request;
    }

    /**
     * create a unique SAS (keyed by a random string)
     * <br>
     * Used by the application
     * @return the created SAS
     */
    public SipApplicationSession createApplicationSession() {
        SipApplicationSessionImpl as = createApplicationSessionImpl();
        as.setShouldBePersisted(); // could delay until ID is requested

        return as;
    }

    /**
     * Create a unique SAS (keyed by a random string)
     * <br>
     * Used internally
     * @return the created SAS
     */
    public SipApplicationSessionImpl createApplicationSessionImpl() {
        SipApplicationSessionImpl as = m_SipSessionManager.createSipApplicationSession(m_Ctx.getSipApplicationListeners());

        return as;
    }

    public SipServletRequestImpl createRequestImpl(SipApplicationSessionImpl appSession, String method, Address from, Address to, boolean sameCallID, SipServletRequestImpl origRequest) {
        SipServletRequestImpl request = m_ConcreteSipFactory.createRequestImpl(appSession, method, from, to, sameCallID, origRequest);
        postCreateRequest(request);

        return request;
    }

    public void initKeyMethod(Method m) {
        sessionKey = m;
    }

    /**
     * The SipApplicationKey annotation is processed by a classloader specific for
     * deployment. We need to make sure that the classloader is the same as this
     * application.
     *
     * For any other annotation, it is not an issue. However 289 specification mentions
     * that SAK is annotated on a static method. So, the execution will happen on the
     * the class declared using the deployment classloader.
     */
    public synchronized Method getSessionKey(ClassLoader cl) {
        if (sessionKey.getDeclaringClass().getClassLoader() != cl) {
           try {
                Class c = cl.loadClass(sessionKey.getDeclaringClass().getName());
                sessionKey =
                c.getMethod(sessionKey.getName(), sessionKey.getParameterTypes());
           } catch (Exception e) {
                logger.log(Level.WARNING, e.getMessage(), e);
           }
        }
        return sessionKey;
    }

    /**
     * @return Returns the m_sipApplicationListeners.
     */
    public SipApplicationListeners getSipApplicationListeners() {
        return m_Ctx.getSipApplicationListeners();
    }

    private void postCreateRequest(SipServletRequestImpl request) {
        request.setRole(m_ApplicationName);

        if (request.getSessionImpl().getHandler() == null) {
            try {
                request.getSessionImpl().setHandler(m_SipApplication.getDefaultServlet());
            } catch (ServletException ignore) {
            }
        }
    }

    /**
     * Implements the jsr289 session key lookup concept
     * Checks if there is any ref to clear and then if the SAS that we are
     * looking for is already created
     */
    public SipApplicationSessionImpl createApplicationSession(SipServletRequestImpl request) {
        SipApplicationSessionImpl sas = null;

        sas = extractUriEncodedSas(request);

        if (sas != null) {
            return sas;
        }

        String beKey = request.getBeKey();
        sas = extractSasFromBekeyAndSak(request, beKey);

        if (sas != null) {
            return sas;
        }

        if (beKey != null) {
            return m_SipSessionManager.createSipApplicationSession(SipApplicationSessionUtil.createSasId(beKey, m_Ctx.getAppName(), UUIDUtil.randomUUID()), m_Ctx.getSipApplicationListeners());
        } else {
            return createApplicationSessionImpl();
        }
    }

    private SipApplicationSessionImpl extractUriEncodedSas(SipServletRequestImpl request) {
        try {
            String uriEncodedSasId = UriUtil.getAndDecodeParameter(request.getRequestURI(), URIImpl.SASID_PARAM);

            if (uriEncodedSasId != null) {
                String appName = SipApplicationSessionUtil.getApplicationName(uriEncodedSasId);

                if (!appName.equals(m_ApplicationName)) {
                    logger.log(Level.WARNING, "com.ericsson.ssa.config.SipFactoryFacade.appname_mismatch", new Object[] {
                            appName, m_ApplicationName
                        });
                } else {
                    SipApplicationSessionImpl proposedSas = m_SipSessionManager.findSipApplicationSession(uriEncodedSasId);

                    if ((proposedSas != null) && proposedSas.isValid()) {
                        return proposedSas;
                    }

                    logger.log(Level.WARNING, "com.ericsson.ssa.config.SipFactoryFacade.uri_encoded_sas_not_found");
                }
            }
        } catch (UnsupportedEncodingException e1) {
            logger.log(Level.WARNING, "com.ericsson.ssa.config.SipFactoryFacade.uri_encoded_sas_corrupt", e1);
        } catch (RemoteLockException e) {
            throw new RemoteLockRuntimeException(e);
        }

        return null;
    }

    private SipApplicationSessionImpl extractSasFromBekeyAndSak(SipServletRequestImpl request, String beKey) {
        if (sessionKey != null) {
            // Cleanup move to xxx
            //    if (logger.isLoggable(Level.FINE))
            //        logger.log(Level.FINE, "Cleanup Removing SAS : " + pr.get());
            //    activeSessions.remove(pr.getSessionId());
            String sakKey = null;

            // Save Current Context ClassLoader
            ClassLoader storedClassLoader = Thread.currentThread().getContextClassLoader();
            try {
                ClassLoader cl = m_Ctx.getLoader().getClassLoader();
                Thread.currentThread().setContextClassLoader(cl);
                InvocationContextUtil.preInvoke(m_Ctx);
                sakKey = (String) getSessionKey(cl).invoke(null, request);
               
            } catch (Exception e) {
                logger.log(Level.WARNING, "com.ericsson.ssa.config.SipFactoryFacade.session_key_not_working", e);
            }finally {
                InvocationContextUtil.postInvoke(m_Ctx);
                Thread.currentThread().setContextClassLoader(storedClassLoader);
            }

            // NOTE, (SAK == null) is interpreted as if the application do not want to tie this
            // request to an existing SAS, i.e. as if the SAK mechanism was temporarily disabled.
            // The request will thus be tied to a new SAS where the ID contains a UUID (and possibly a bekey).
            if (sakKey != null) { 
                String key = null;

                if (beKey != null) {
                    key = beKey;

                    if (!beKey.equals(sakKey)) {
                        logger.log(Level.WARNING, "com.ericsson.ssa.config.SipFactoryFacade.session_key_not_match_bekey", beKey);
                    }
                } else {
                    key = sakKey;
                }

                String sasId = SipApplicationSessionUtil.createSasId(key, m_Ctx.getAppName(), null);

                // There is a key now look for an existing SAS
                SipApplicationSessionImpl ref = null;

                try {
                    ref = m_SipSessionManager.findSipApplicationSession(sasId);
                } catch (RemoteLockException e) {
                    throw new RemoteLockRuntimeException(e);
                }

                if ((ref != null) && !ref.isValid()) {
                    m_SipSessionManager.removeSipApplicationSession(ref);
                    ref = null;
                }

                if (ref != null) { // There is a cached value to be recycled

                    return ref;
                }

                // Need to create a new SAS and store it
                return m_SipSessionManager.createSipApplicationSession(sasId, m_Ctx.getSipApplicationListeners());
            }
        }

        return null;
    }

    public AuthInfo createAuthInfo() {
        return new AuthInfoImpl();
    }

    public SipApplicationSession createApplicationSessionByAppName(String sipAppName) throws IllegalStateException {
        SipApplicationSession sas = null;

        if (sipAppName == null) {
            // We should probably throw an exception, in the new upcoming spec
            throw new IllegalStateException("Application Name Not Specified");
        }
        //TODO Likely to be changed to the following in the updated spec
        //        else if (sipAppName.equals(m_ApplicationName)){          
        //             throw new IllegalStateException("Method cannot be called from same applicaton");
        //        }
        else {
            String internalSipFactoryey = "sip/" + sipAppName + "/SipFactory";
            SipFactory sf = (SipFactoryMap.getInstance()).getSipFactoryFacade(internalSipFactoryey);

            if (sf == null) {
                // Application not deployed
                throw new IllegalStateException("SipFactory for " + sipAppName + " could not be retreived");
            }

            sas = sf.createApplicationSession();
        }

        return sas;
    }

    public SipApplicationSession createApplicationSessionByKey(String sipApplicationKey) throws IllegalStateException {
        if (sipApplicationKey == null) {
            throw new IllegalArgumentException("The key must not be null.");
        }

        String sasId = SipApplicationSessionUtil.createSasId(sipApplicationKey, m_Ctx.getAppName(), null);

        // There is a key now look for an existing SAS
        SipApplicationSessionImpl ref = null;

        try {
            ref = m_SipSessionManager.findSipApplicationSession(sasId);

            if ((ref != null) && !ref.isValid()) {
                m_SipSessionManager.removeSipApplicationSession(ref);
                ref = null;
            }
        } catch (RemoteLockException ex) {
            throw new RemoteLockRuntimeException(ex);
        }

        if (ref != null) { // There is a cached value to be recycled

            return ref;
        }

        // Need to create a new SAS and store it
        SipApplicationSessionImpl sas = m_SipSessionManager.createSipApplicationSession(sasId, m_Ctx.getSipApplicationListeners());
        sas.setShouldBePersisted(); // on a SAS created by key we want to persist

        return sas;
    }
}
TOP

Related Classes of com.ericsson.ssa.config.SipFactoryFacade

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.