/* * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.web.tomcat.service.session; import gov.nist.javax.sip.SipProviderImpl; import gov.nist.javax.sip.SipStackImpl; import gov.nist.javax.sip.stack.SIPDialog; import javax.sip.SipStack; import org.apache.catalina.Container; import org.apache.catalina.Engine; import org.apache.catalina.Service; import org.apache.catalina.connector.Connector; import org.apache.log4j.Logger; import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; import org.mobicents.servlet.sip.core.session.SipSessionKey; import org.mobicents.servlet.sip.message.SipFactoryImpl; import org.mobicents.servlet.sip.startup.SipService; /** * Common superclass of ClusteredSipSession types that use JBossCache * as their distributed cache. * * @author <A HREF="mailto:jean.deruelle@gmail.com">Jean Deruelle</A> * */ public abstract class JBossCacheClusteredSipSession extends ClusteredSipSession { private static transient final Logger logger = Logger.getLogger(JBossCacheClusteredSipSession.class); /** * Our proxy to the cache. */ protected transient ConvergedJBossCacheService proxy_; protected JBossCacheClusteredSipSession(SipSessionKey key, SipFactoryImpl sipFactoryImpl, MobicentsSipApplicationSession mobicentsSipApplicationSession) { super(key, sipFactoryImpl, mobicentsSipApplicationSession, ((JBossCacheSipManager)mobicentsSipApplicationSession.getSipContext().getSipManager()).getUseJK()); int maxUnrep = ((JBossCacheSipManager)mobicentsSipApplicationSession.getSipContext().getSipManager()).getMaxUnreplicatedInterval() * 1000; setMaxUnreplicatedInterval(maxUnrep); establishProxy(); } /** * Initialize fields marked as transient after loading this session from the * distributed store * * @param manager * the manager for this session */ public void initAfterLoad(JBossCacheSipManager manager) { sipFactory = manager.getSipFactoryImpl(); if(proxy != null) { proxy.setSipFactoryImpl(sipFactory); } if(b2buaHelper != null) { b2buaHelper.setSipFactoryImpl(sipFactory); b2buaHelper.setSipManager(manager); } //inject the dialog into the available sip stacks if(logger.isDebugEnabled()) { logger.debug("dialog to inject " + sessionCreatingDialog); if(sessionCreatingDialog != null) { logger.debug("dialog id of the dialog to inject " + sessionCreatingDialog.getDialogId()); } } if(sessionCreatingDialogId != null && sessionCreatingDialogId.length() > 0) { Container context = manager.getContainer(); Container container = context.getParent().getParent(); if(container instanceof Engine) { Service service = ((Engine)container).getService(); if(service instanceof SipService) { Connector[] connectors = service.findConnectors(); for (Connector connector : connectors) { SipStack sipStack = (SipStack) connector.getProtocolHandler().getAttribute(SipStack.class.getSimpleName()); if(sipStack != null && sipStack.getSipProviders().hasNext()) { sessionCreatingDialog = ((SipStackImpl)sipStack).getDialog(sessionCreatingDialogId); if(logger.isDebugEnabled()) { logger.debug("dialog injected " + sessionCreatingDialog); } } } } } } // Since attribute map may be transient, we may need to populate it // from the underlying store. populateAttributes(); // Notify all attributes of type SipSessionActivationListener this.activate(); // We are no longer outdated vis a vis distributed cache clearOutdated(); } /** * Gets a reference to the JBossCacheService. */ protected void establishProxy() { if (proxy_ == null) { proxy_ = (ConvergedJBossCacheService)((JBossCacheSipManager) getSipApplicationSession().getSipContext().getSipManager()).getCacheService(); // still null??? if (proxy_ == null) { throw new RuntimeException( "JBossCacheClusteredSession: Cache service is null."); } } } protected abstract void populateAttributes(); /** * Override the superclass to additionally reset this class' fields. * <p> * <strong>NOTE:</strong> It is not anticipated that this method will be * called on a ClusteredSession, but we are overriding the method to be * thorough. * </p> */ // public void recycle() { // super.recycle(); // // proxy_ = null; // } /** * Increment our version and place ourself in the cache. */ public synchronized void processSessionRepl() { // Replicate the session. if (logger.isDebugEnabled()) { logger.debug("processSessionRepl(): session is dirty. Will increment " + "version from: " + getVersion() + " and replicate."); } this.incrementVersion(); proxy_.putSipSession(getId(), this); sessionAttributesDirty = false; sessionMetadataDirty = false; updateLastReplicated(); } /** * Overrides the superclass impl by doing nothing if <code>localCall</code> * is <code>false</code>. The JBossCacheManager will already be aware of a * remote invalidation and will handle removal itself. */ protected void removeFromManager(boolean localCall, boolean localOnly) { if (localCall) { super.removeFromManager(localCall, localOnly); } } protected Object removeAttributeInternal(String name, boolean localCall, boolean localOnly) { return removeJBossInternalAttribute(name, localCall, localOnly); } protected Object removeJBossInternalAttribute(String name) { throw new UnsupportedOperationException( "removeJBossInternalAttribute(String) " + "is not supported by JBossCacheClusteredSession; use " + "removeJBossInternalAttribute(String, boolean, boolean"); } protected abstract Object removeJBossInternalAttribute(String name, boolean localCall, boolean localOnly); }