/*
* 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.sip;
import com.ericsson.ssa.sip.timer.ServletTimerImpl;
import com.ericsson.ssa.sip.timer.ServletTimerStore;
import com.sun.enterprise.ee.web.sessmgmt.LoadProcessingGovernor;
import org.jvnet.glassfish.comms.util.LogUtil;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A session manager capable of persisting SipSessions,
* SipApplicationSessions, and ServletTimers.
*
* @author jluehe
*/
public abstract class PersistentSipSessionManagerBase
extends SipSessionManagerBase {
private static final Logger log = LogUtil.SIP_LOGGER.getLogger();
// The persistent store for SipSessions
private SipSessionStore sipSessionStore;
// The persistent store for SipApplicationSessions
private SipApplicationSessionStore sipApplicationSessionStore;
// The persistent store for ServletTimers
private ServletTimerStore servletTimerStore;
/**
* Gets the SipSession with the given id.
*
* This method first checks the active cache for a SipSession with the
* given id. If not found, it queries the persistent session store.
*
* @return The SipSession with the given id, or null if not found
*/
public SipSessionDialogImpl findSipSession(String id)
throws RemoteLockException {
return findSipSession(id, true);
}
public SipSessionDialogImpl findSipSession(String id,
boolean loadDependencies)
throws RemoteLockException {
SipSessionDialogImpl sipSession = super.findSipSession(id);
if (sipSession != null) {
return sipSession;
}
ClassLoader webappCL = null;
ClassLoader curCL = null;
if ((getContext() != null) && (getContext().getLoader() != null)) {
webappCL = getContext().getLoader().getClassLoader();
curCL = Thread.currentThread().getContextClassLoader();
}
if ((webappCL != null) && (curCL != webappCL)) {
try {
Thread.currentThread().setContextClassLoader(webappCL);
LoadProcessingGovernor.incrementCurrentLoads();
sipSession = swapInSipSession(id, loadDependencies);
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.swap_in_sip_session_error", id);
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
} finally {
Thread.currentThread().setContextClassLoader(curCL);
}
} else {
try {
LoadProcessingGovernor.incrementCurrentLoads();
sipSession = swapInSipSession(id, loadDependencies);
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.swap_in_sip_session_error", id);
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
}
}
return sipSession;
}
/**
* Removes the given SipSession from both the active cache and the
* persistent session store of this session manager,
*
* @param sipSession The SipSession to be removed
*/
public void removeSipSession(SipSessionDialogImpl sipSession) {
super.removeSipSession(sipSession);
if (sipSessionStore != null) {
try {
sipSessionStore.remove(sipSession.getId());
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.remove_sip_session_from_store_error", sipSession.getId());
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
}
}
}
/**
* Removes the given SipSession from only the active cache
*
* @param sipSession The SipSession to be removed
*/
public void removeSipSessionFromCache(SipSessionDialogImpl sipSession) {
super.removeSipSession(sipSession);
}
/**
* Removes the given SipSession from only the active cache
*
* @param sipSessionId The id of the SipSession to be removed
*/
public void removeSipSessionFromCache(String sipSessionId) {
super.removeSipSession(sipSessionId);
}
/**
* Persists the given SipSession.
*
* @param sipSession The SipSession to be persisted
*/
public void saveSipSession(SipSessionDialogImpl sipSession)
throws IOException {
if (sipSessionStore != null) {
sipSessionStore.save(sipSession);
}
}
/**
* Swaps in the SipSession with the given id from the persistent session
* store of this session manager.
*
* @return The SipSession with the given id, or null if not found
*/
protected SipSessionDialogImpl swapInSipSession(String id,
boolean loadDependencies)
throws IOException, RemoteLockException {
if (sipSessionStore == null) {
return null;
}
SipSessionDialogImpl sipSession = sipSessionStore.load(id, loadDependencies);
if (sipSession == null) {
return null;
}
boolean isActivated = sipSession.activate();
if (!isActivated) {
return null;
}
return sipSession;
}
/**
* Gets the SipApplicationSession with the given id.
*
* This method first checks the active cache for a SipApplicationSession
* with the given id. If not found, it queries the persistent session
* store.
*
* @return The SipApplicationSession with the given id, or null if not
* found
*/
public SipApplicationSessionImpl findSipApplicationSession(String id)
throws RemoteLockException {
return findSipApplicationSession(id, false);
}
/**
* Gets the SipApplicationSession with the given id.
*
* This method first checks the active cache for a SipApplicationSession
* with the given id. If not found, it queries the persistent session
* store.
*
* @return The SipApplicationSession with the given id, or null if not
* found
*/
public SipApplicationSessionImpl findSipApplicationSession(String id,
boolean force) throws RemoteLockException {
SipApplicationSessionImpl sas = super.findSipApplicationSession(id);
if (sas != null) {
return sas;
}
ClassLoader webappCL = null;
ClassLoader curCL = null;
if ((getContext() != null) && (getContext().getLoader() != null)) {
webappCL = getContext().getLoader().getClassLoader();
curCL = Thread.currentThread().getContextClassLoader();
}
if ((webappCL != null) && (curCL != webappCL)) {
try {
Thread.currentThread().setContextClassLoader(webappCL);
LoadProcessingGovernor.incrementCurrentLoads();
sas = swapInSipApplicationSession(id, force);
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.swap_in_sip_application_session_error", id);
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
} finally {
Thread.currentThread().setContextClassLoader(curCL);
}
} else {
try {
LoadProcessingGovernor.incrementCurrentLoads();
sas = swapInSipApplicationSession(id, force);
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.swap_in_sip_application_session_error", id);
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
}
}
return sas;
}
/**
* Removes the given SipApplicationSession from both the active cache
* and the persistent session store of this session manager,
*
* @param sas The SipApplicationSession to be removed
*/
public void removeSipApplicationSession(SipApplicationSessionImpl sas) {
super.removeSipApplicationSession(sas);
if (sipApplicationSessionStore != null) {
try {
sipApplicationSessionStore.remove(sas.getId());
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.remove_sip_application_session_from_store_error", sas.getId());
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
}
}
}
/**
* Removes the given SipApplicationSession from only the active cache
*
* @param sas The SipApplicationSession to be removed
*/
public void removeSipApplicationSessionFromCache(SipApplicationSessionImpl sas) {
super.removeSipApplicationSession(sas);
}
/**
* Gets the SipApplicationSession with the given id
* from the active cache only
*
* @return The SipApplicationSession with the given id, or null if not
* found
*/
public SipApplicationSessionImpl findSipApplicationSessionFromCacheOnly(String id) {
SipApplicationSessionImpl result = null;
try {
result = super.findSipApplicationSession(id);
} catch (RemoteLockException ex) {
// Could never happen, since we are fetching from the local active cache!!
if (log.isLoggable(Level.WARNING)) {
log.log(Level.WARNING, "sip.stack.remote_lock_in_local_cache", new Object[]{"SipApplicationSession", id});
}
}
return result;
}
/**
* Gets the SipApplicationSession with the given id
* from the active cache only
*
* @return The SipSession with the given id, or null if not
* found
*/
public SipSessionDialogImpl findSipSessionFromCacheOnly(String id) {
SipSessionDialogImpl result = null;
try {
result = super.findSipSession(id);
} catch (RemoteLockException ex) {
// Could never happen, since we are fetching from the local active cache!!
if (log.isLoggable(Level.WARNING)) {
log.log(Level.WARNING, "sip.stack.remote_lock_in_local_cache", new Object[]{"SipSession", id});
}
}
return result;
}
/**
* Persists the given SipApplicationSession.
*
* @param sas The SipApplicationSession to be persisted
*/
public void saveSipApplicationSession(SipApplicationSessionImpl sas)
throws IOException {
if (sipApplicationSessionStore != null) {
sipApplicationSessionStore.save(sas);
}
}
/**
* Swaps in the SipApplicationSession with the given id from the
* persistent session store of this session manager.
*
* @return The SipApplicationSession with the given id, or null if not
* found
*/
protected SipApplicationSessionImpl swapInSipApplicationSession(String id,
boolean force)
throws IOException, RemoteLockException {
if (sipApplicationSessionStore == null) {
return null;
}
SipApplicationSessionImpl sas = sipApplicationSessionStore.load(id);
if (sas == null) {
return null;
}
if (!sas.isValid()) {
LogUtil.SIP_LOGGER.getLogger().log(Level.WARNING, "Swapped-in " + sas + " is invalid or has expired");
return null;
}
boolean isActivated = sas.activate();
if (!isActivated) {
return null;
}
return sas;
}
/**
* Gets the ServletTimer with the given id.
*
* This method first checks the active cache for a ServletTimer with the
* given id. If not found, it queries the persistent session store.
*
* @return The ServletTimer with the given id, or null if not found
*/
public ServletTimerImpl findServletTimer(String id)
throws RemoteLockException {
return findServletTimer(id, true);
}
public ServletTimerImpl findServletTimer(String id,
boolean loadDependencies)
throws RemoteLockException {
ServletTimerImpl servletTimer = super.findServletTimer(id);
if (servletTimer != null) {
return servletTimer;
}
ClassLoader webappCL = null;
ClassLoader curCL = null;
if ((getContext() != null) && (getContext().getLoader() != null)) {
webappCL = getContext().getLoader().getClassLoader();
curCL = Thread.currentThread().getContextClassLoader();
}
if ((webappCL != null) && (curCL != webappCL)) {
try {
Thread.currentThread().setContextClassLoader(webappCL);
LoadProcessingGovernor.incrementCurrentLoads();
servletTimer = swapInServletTimer(id, loadDependencies);
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.swap_in_servlet_timer_error", id);
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
} finally {
Thread.currentThread().setContextClassLoader(curCL);
}
} else {
try {
LoadProcessingGovernor.incrementCurrentLoads();
servletTimer = swapInServletTimer(id, loadDependencies);
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.swap_in_servlet_timer_error", id);
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
}
}
return servletTimer;
}
/**
* Removes the given ServletTimer from both the active cache and the
* persistent session store of this session manager,
*
* @param servletTimer The ServletTimer to be removed
*/
public void removeServletTimer(ServletTimerImpl servletTimer) {
super.removeServletTimer(servletTimer);
if (servletTimerStore != null) {
try {
servletTimerStore.remove(servletTimer.getId());
} catch (IOException ioe) {
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, "sipstack.remove_servlet_timer_from_store_error", servletTimer.getId());
LogUtil.SIP_LOGGER.getLogger().log(Level.SEVERE, ioe.getMessage(), ioe);
}
}
}
/**
* Removes the given ServletTimer from only the active cache
*
* @param servletTimer The ServletTimer to be removed
*/
public void removeServletTimerFromCache(ServletTimerImpl servletTimer) {
super.removeServletTimer(servletTimer);
}
/**
* Gets the ServletTimer with the given id
* from the active cache only
*
* @return The ServletTimer with the given id, or null if not
* found
*/
public ServletTimerImpl findServletTimerFromCacheOnly(String id) {
ServletTimerImpl result = null;
try {
result = super.findServletTimer(id);
} catch (RemoteLockException ex) {
// Could never happen, since we are fetching from the local active cache!!
if (log.isLoggable(Level.WARNING)) {
log.log(Level.WARNING, "sip.stack.remote_lock_in_local_cache", new Object[]{"ServletTimer", id});
}
}
return result;
}
/**
* Persists the given ServletTimer.
*
* @param servletTimer The ServletTimer to be persisted
*/
public void saveServletTimer(ServletTimerImpl servletTimer)
throws IOException {
if (servletTimerStore != null) {
servletTimerStore.save(servletTimer);
}
}
/**
* Swaps in the ServletTimer with the given id from the persistent session
* store of this session manager.
*
* @return The ServletTimer with the given id, or null if not found
*/
protected ServletTimerImpl swapInServletTimer(String id,
boolean loadDependencies)
throws IOException, RemoteLockException {
if (servletTimerStore == null) {
return null;
}
ServletTimerImpl servletTimer = servletTimerStore.load(id, loadDependencies);
if (servletTimer == null) {
return null;
}
boolean isActivated = servletTimer.activate();
if (!isActivated) {
return null;
}
return servletTimer;
}
/**
* Sets the persistent store for SipSessions on this session manager.
*
* @param store The persistent store for SipSessions
*/
public void setSipSessionStore(SipSessionStore store) {
sipSessionStore = store;
sipSessionStore.setSipSessionManager(this);
}
/**
* Gets the persistent store for SipSessions from this session manager.
*
* @return The persistent store for SipSessions
*/
public SipSessionStore getSipSessionStore() {
return sipSessionStore;
}
/**
* Sets the persistent store for SipApplicationSessions on this session
* manager.
*
* @param store The persistent store for SipApplicationSessions
*/
public void setSipApplicationSessionStore(SipApplicationSessionStore store) {
sipApplicationSessionStore = store;
sipApplicationSessionStore.setSipSessionManager(this);
}
/**
* Gets the persistent store for SipApplicationSessions from this session
* manager.
*
* @return The persistent store for SipApplicationSessions
*/
public SipApplicationSessionStore getSipApplicationSessionStore() {
return sipApplicationSessionStore;
}
/**
* Sets the persistent store for ServletTimers on this session
* manager.
*
* @param store The persistent store for ServletTimers
*/
public void setServletTimerStore(ServletTimerStore store) {
servletTimerStore = store;
servletTimerStore.setSipSessionManager(this);
}
/**
* Gets the persistent store for ServletTimers from this session
* manager.
*
* @return The persistent store for ServletTimers
*/
public ServletTimerStore getServletTimerStore() {
return servletTimerStore;
}
/**
* Purges any expired SIP artifacts from this manager's active caches and
* persistent stores as a periodic task.
*/
public void backgroundProcess() {
// There is no need to remove any SIP artifacts from any of the
// active caches, since they are automatically removed from them
// upon their invalidation or expiration.
if (sipApplicationSessionStore != null) {
sipApplicationSessionStore.processExpires();
}
if (sipSessionStore != null) {
sipSessionStore.processExpires();
}
if (servletTimerStore != null) {
servletTimerStore.processExpires();
}
}
/**
* Releases any resources held by this SipSessionManager.during
* undeployment.
*/
public void release() {
super.release();
if (sipSessionStore != null) {
try {
sipSessionStore.clear();
sipSessionStore = null;
} catch (IOException ioe) {
// Ignore
}
}
if (sipApplicationSessionStore != null) {
try {
sipApplicationSessionStore.clear();
sipApplicationSessionStore = null;
} catch (IOException ioe) {
// Ignore
}
}
if (servletTimerStore != null) {
try {
servletTimerStore.clear();
servletTimerStore = null;
} catch (IOException ioe) {
// Ignore
}
}
}
}