PageRenderTime 135ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/sip-servlets/sip-servlets-tomcat-jboss4/src/main/java/org/jboss/web/tomcat/service/session/JBossCacheClusteredSipSession.java

http://mobicents.googlecode.com/
Java | 300 lines | 198 code | 30 blank | 72 comment | 51 complexity | a4ef521d7eb735982570ec514e610a63 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011, Red Hat, Inc. and individual contributors
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.web.tomcat.service.session;
  23. import gov.nist.javax.sip.SipStackImpl;
  24. import java.text.ParseException;
  25. import java.util.Map;
  26. import java.util.Map.Entry;
  27. import java.util.concurrent.ConcurrentHashMap;
  28. import javax.sip.SipStack;
  29. import org.apache.catalina.Container;
  30. import org.apache.catalina.Engine;
  31. import org.apache.catalina.Service;
  32. import org.apache.log4j.Logger;
  33. import org.mobicents.servlet.sip.core.SipService;
  34. import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession;
  35. import org.mobicents.servlet.sip.core.session.MobicentsSipSessionKey;
  36. import org.mobicents.servlet.sip.core.session.SessionManagerUtil;
  37. import org.mobicents.servlet.sip.core.session.SipSessionKey;
  38. import org.mobicents.servlet.sip.message.B2buaHelperImpl;
  39. import org.mobicents.servlet.sip.message.SipFactoryImpl;
  40. import org.mobicents.servlet.sip.proxy.ProxyImpl;
  41. /**
  42. * Common superclass of ClusteredSipSession types that use JBossCache
  43. * as their distributed cache.
  44. *
  45. * @author <A HREF="mailto:jean.deruelle@gmail.com">Jean Deruelle</A>
  46. *
  47. */
  48. public abstract class JBossCacheClusteredSipSession extends ClusteredSipSession {
  49. private static final Logger logger = Logger.getLogger(JBossCacheClusteredSipSession.class);
  50. /**
  51. * Our proxy to the cache.
  52. */
  53. protected transient ConvergedJBossCacheService proxy_;
  54. protected JBossCacheClusteredSipSession(SipSessionKey key,
  55. SipFactoryImpl sipFactoryImpl,
  56. MobicentsSipApplicationSession mobicentsSipApplicationSession, JBossCacheManager jBossCacheManager) {
  57. super(key, sipFactoryImpl, mobicentsSipApplicationSession,
  58. jBossCacheManager.getUseJK());
  59. int maxUnrep = jBossCacheManager.getMaxUnreplicatedInterval() * 1000;
  60. setMaxUnreplicatedInterval(maxUnrep);
  61. establishProxy(jBossCacheManager);
  62. }
  63. /**
  64. * Initialize fields marked as transient after loading this session from the
  65. * distributed store
  66. *
  67. * @param manager
  68. * the manager for this session
  69. */
  70. public void initAfterLoad(JBossCacheSipManager manager) {
  71. sipFactory = (SipFactoryImpl) manager.getMobicentsSipFactory();
  72. // Since attribute map may be transient, we may need to populate it
  73. // from the underlying store.
  74. populateMetaData();
  75. if(proxy != null) {
  76. proxy.setMobicentsSipFactory(sipFactory);
  77. }
  78. if(b2buaHelper != null) {
  79. b2buaHelper.setMobicentsSipFactory(sipFactory);
  80. b2buaHelper.setSipManager(manager);
  81. }
  82. //inject the dialog into the available sip stacks
  83. if(logger.isDebugEnabled()) {
  84. logger.debug("dialog to inject " + sessionCreatingDialogId);
  85. if(sessionCreatingDialogId != null) {
  86. logger.debug("dialog id of the dialog to inject " + sessionCreatingDialogId);
  87. }
  88. }
  89. if(sessionCreatingDialogId != null && sessionCreatingDialogId.length() > 0) {
  90. Container context = manager.getContainer();
  91. Container container = context.getParent().getParent();
  92. if(container instanceof Engine) {
  93. Service service = ((Engine)container).getService();
  94. if(service instanceof SipService) {
  95. SipService sipService = (SipService) service;
  96. SipStack sipStack = sipService.getSipStack();
  97. if(sipStack != null) {
  98. sessionCreatingDialog = ((SipStackImpl)sipStack).getDialog(sessionCreatingDialogId);
  99. if(logger.isDebugEnabled()) {
  100. logger.debug("dialog injected " + sessionCreatingDialog);
  101. }
  102. }
  103. }
  104. }
  105. }
  106. // Since attribute map may be transient, we may need to populate it
  107. // from the underlying store.
  108. populateAttributes();
  109. // Notify all attributes of type SipSessionActivationListener
  110. this.activate();
  111. // We are no longer outdated vis a vis distributed cache
  112. clearOutdated();
  113. }
  114. /**
  115. * Gets a reference to the JBossCacheService.
  116. * @param jBossCacheManager
  117. */
  118. protected void establishProxy(JBossCacheManager jBossCacheManager) {
  119. if (proxy_ == null) {
  120. proxy_ = (ConvergedJBossCacheService) jBossCacheManager.getCacheService();
  121. // still null???
  122. if (proxy_ == null) {
  123. throw new RuntimeException(
  124. "JBossCacheClusteredSession: Cache service is null.");
  125. }
  126. }
  127. }
  128. protected abstract void populateAttributes();
  129. /**
  130. * Override the superclass to additionally reset this class' fields.
  131. * <p>
  132. * <strong>NOTE:</strong> It is not anticipated that this method will be
  133. * called on a ClusteredSession, but we are overriding the method to be
  134. * thorough.
  135. * </p>
  136. */
  137. // public void recycle() {
  138. // super.recycle();
  139. //
  140. // proxy_ = null;
  141. // }
  142. protected void populateMetaData() {
  143. final String sipAppSessionId = sipApplicationSessionKey.getId();
  144. final String sipSessionId = getHaId();
  145. Long ct = (Long) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, CREATION_TIME);
  146. if(ct != null) {
  147. creationTime = ct;
  148. }
  149. Integer ip = (Integer) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, INVALIDATION_POLICY);
  150. if(ip != null) {
  151. invalidationPolicy = ip;
  152. }
  153. handlerServlet = (String) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, HANDLER);
  154. Boolean valid = (Boolean) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, IS_VALID);
  155. if(valid != null) {
  156. setValid(valid);
  157. }
  158. state = (State) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, STATE);
  159. Long cSeq = (Long) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, CSEQ);
  160. if(cSeq != null) {
  161. cseq = cSeq;
  162. }
  163. Boolean iwr = (Boolean) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, INVALIDATE_WHEN_READY);
  164. if(iwr != null) {
  165. invalidateWhenReady = iwr;
  166. }
  167. Boolean rti = (Boolean) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, READY_TO_INVALIDATE);
  168. if(rti != null) {
  169. readyToInvalidate = rti;
  170. }
  171. sessionCreatingDialogId = (String) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, DIALOG_ID);
  172. proxy = (ProxyImpl) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, PROXY);
  173. Integer size = (Integer) proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, B2B_SESSION_SIZE);
  174. String[][] sessionArray = (String[][])proxy_.getSipSessionMetaData(sipAppSessionId, sipSessionId, B2B_SESSION_MAP);
  175. if(logger.isDebugEnabled()) {
  176. logger.debug("b2bua session array size = " + size + ", value = " + sessionArray);
  177. }
  178. if(size != null && sessionArray != null) {
  179. Map<MobicentsSipSessionKey, MobicentsSipSessionKey> sessionMap = new ConcurrentHashMap<MobicentsSipSessionKey, MobicentsSipSessionKey>();
  180. for (int i = 0; i < size; i++) {
  181. String key = sessionArray[0][i];
  182. String value = sessionArray[1][i];
  183. try {
  184. SipSessionKey sipSessionKeyKey = SessionManagerUtil.parseSipSessionKey(key);
  185. SipSessionKey sipSessionKeyValue = SessionManagerUtil.parseSipSessionKey(value);
  186. sessionMap.put(sipSessionKeyKey, sipSessionKeyValue);
  187. } catch (ParseException e) {
  188. logger.warn("couldn't parse a deserialized sip session key from the B2BUA", e);
  189. }
  190. }
  191. if(b2buaHelper == null) {
  192. b2buaHelper = new B2buaHelperImpl();
  193. }
  194. b2buaHelper.setSessionMap(sessionMap);
  195. }
  196. isNew = false;
  197. }
  198. /**
  199. * Increment our version and place ourself in the cache.
  200. */
  201. public synchronized void processSessionRepl() {
  202. // Replicate the session.
  203. final String sipAppSessionKey = sipApplicationSessionKey.getId();
  204. final String sipSessionKey = getHaId();
  205. if (logger.isDebugEnabled()) {
  206. logger.debug("processSessionRepl(): replicating sip session " + sipSessionKey);
  207. }
  208. if(isNew) {
  209. proxy_.putSipSessionMetaData(sipAppSessionKey, sipSessionKey, CREATION_TIME, creationTime);
  210. proxy_.putSipSessionMetaData(sipAppSessionKey, sipSessionKey, INVALIDATION_POLICY, invalidationPolicy);
  211. isNew = false;
  212. }
  213. if(sessionMetadataDirty) {
  214. if (logger.isDebugEnabled()) {
  215. logger.debug("processSessionRepl(): session metadata is dirty.");
  216. }
  217. for (Entry<String, Object> entry : metaModifiedMap_.entrySet()) {
  218. proxy_.putSipSessionMetaData(sipAppSessionKey, sipSessionKey, entry.getKey(), entry.getValue());
  219. }
  220. metaModifiedMap_.clear();
  221. if(proxy != null) {
  222. proxy_.putSipSessionMetaData(sipAppSessionKey, sipSessionKey, PROXY, proxy);
  223. }
  224. if(b2buaHelper != null) {
  225. final Map<MobicentsSipSessionKey, MobicentsSipSessionKey> sessionMap = b2buaHelper.getSessionMap();
  226. final int size = sessionMap.size();
  227. final String[][] sessionArray = new String[2][size];
  228. int i = 0;
  229. for (Entry<MobicentsSipSessionKey, MobicentsSipSessionKey> entry : sessionMap.entrySet()) {
  230. sessionArray [0][i] = entry.getKey().toString();
  231. sessionArray [1][i] = entry.getValue().toString();
  232. i++;
  233. }
  234. proxy_.putSipSessionMetaData(sipAppSessionKey, sipSessionKey,B2B_SESSION_SIZE, size);
  235. if(logger.isDebugEnabled()) {
  236. logger.debug("storing b2bua session array " + sessionArray);
  237. }
  238. proxy_.putSipSessionMetaData(sipAppSessionKey, sipSessionKey, B2B_SESSION_MAP, sessionArray);
  239. }
  240. }
  241. this.incrementVersion();
  242. proxy_.putSipSession(sipSessionKey, this);
  243. sessionAttributesDirty = false;
  244. sessionMetadataDirty = false;
  245. sessionLastAccessTimeDirty = false;
  246. updateLastReplicated();
  247. }
  248. /**
  249. * Overrides the superclass impl by doing nothing if <code>localCall</code>
  250. * is <code>false</code>. The JBossCacheManager will already be aware of a
  251. * remote invalidation and will handle removal itself.
  252. */
  253. protected void removeFromManager(boolean localCall, boolean localOnly) {
  254. if (localCall) {
  255. super.removeFromManager(localCall, localOnly);
  256. }
  257. }
  258. protected Object removeAttributeInternal(String name, boolean localCall,
  259. boolean localOnly) {
  260. return removeJBossInternalAttribute(name, localCall, localOnly);
  261. }
  262. protected Object removeJBossInternalAttribute(String name) {
  263. throw new UnsupportedOperationException(
  264. "removeJBossInternalAttribute(String) "
  265. + "is not supported by JBossCacheClusteredSession; use "
  266. + "removeJBossInternalAttribute(String, boolean, boolean");
  267. }
  268. protected abstract Object removeJBossInternalAttribute(String name,
  269. boolean localCall, boolean localOnly);
  270. }