1 7 package org.jboss.web.tomcat.tc5.session; 8 9 import org.apache.catalina.LifecycleException; 10 import org.apache.catalina.Session; 11 import org.apache.catalina.session.StandardManager; 12 import org.apache.catalina.Context; 13 import org.apache.catalina.Globals; 14 import org.jboss.mx.util.MBeanProxyExt; 15 import org.jboss.mx.util.MBeanServerLocator; 16 import org.jboss.ha.httpsession.interfaces.SerializableHttpSession; 17 import org.jboss.ha.httpsession.server.ClusteredHTTPSessionServiceMBean; 18 19 import java.io.IOException ; 20 import javax.ejb.EJBException ; 21 import javax.management.MBeanServer ; 22 import javax.management.ObjectName ; 23 import javax.servlet.http.HttpServletResponse ; 24 import javax.servlet.http.Cookie ; 25 26 import org.jboss.logging.Logger; 27 import org.jboss.metadata.WebMetaData; 28 29 37 public class JBossManagerCMP 38 extends StandardManager 39 implements AbstractJBossManager, JBossManagerCMPMBean 40 { 41 43 46 private static final String info = "JBossManagerCMP/1.0"; 47 48 52 private static Logger log = Logger.getLogger(JBossManagerCMP.class); 53 54 57 private ClusteredHTTPSessionServiceMBean proxy; 58 59 62 private ObjectName clusteredHttpServiceName; 63 64 67 protected ObjectName objectName; 68 69 72 protected boolean started = false; 73 74 77 private boolean useLocalCache = true; 78 79 protected int invalidateSessionPolicy = WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET; 80 protected int replicationType = WebMetaData.REPLICATION_TYPE_SYNC; 81 82 public JBossManagerCMP() 83 { 84 } 85 86 public void init(String name, WebMetaData webMetaData, boolean useJK, boolean useLocalCache) 87 throws ClusteringNotSupportedException 88 { 89 this.useLocalCache = useLocalCache; 90 91 setDistributable(true); 93 this.invalidateSessionPolicy = webMetaData.getInvalidateSessionPolicy(); 94 this.replicationType = webMetaData.getReplicationType(); 95 96 try 98 { 99 clusteredHttpServiceName = new ObjectName ("jboss", "service", "ClusteredHttpSession"); 100 proxy = (ClusteredHTTPSessionServiceMBean) MBeanProxyExt.create(ClusteredHTTPSessionServiceMBean.class, clusteredHttpServiceName); 102 } 103 catch (Throwable e) 104 { 105 log.info("ClusteredHTTPSessionService not found"); 106 throw new ClusteringNotSupportedException("ClusteredHTTPSessionService not found"); 107 } 108 109 try 110 { 111 proxy.setSessionTimeout(14400000); 113 114 objectName = new ObjectName ("jboss.web:service=ClusterManager,WebModule=" + name); 116 117 log.info("ClusteredHTTPSessionService found"); 118 } 119 catch (Throwable e) 120 { 121 log.error("Could not create ObjectName", e); 122 throw new ClusteringNotSupportedException(e.toString()); 123 } 124 } 125 126 public boolean isUseLocalCache() 127 { 128 return useLocalCache; 129 } 130 131 public Integer getLocalActiveSessionCount() 133 { 134 return new Integer (sessions.size()); 135 } 136 137 public ClusteredSession[] getSessions() 138 { 139 ClusteredSession[] sess = new ClusteredSession[0]; 140 141 synchronized (sessions) 142 { 143 sess = (ClusteredSession[]) sessions.values().toArray(sess); 144 } 145 return sess; 146 } 147 148 public int getInvalidateSessionPolicy() 149 { 150 return this.invalidateSessionPolicy; 151 } 152 153 public int getReplicationType() 154 { 155 return replicationType; 156 } 157 158 159 161 164 public Session createSession() 165 { 166 ClusteredSessionCMP session = new ClusteredSessionCMP(this); 167 168 session.setNew(true); 169 session.setCreationTime(System.currentTimeMillis()); 170 session.setMaxInactiveInterval(this.maxInactiveInterval); 171 172 String sessionId = this.getNextId(); 173 String jvmRoute = this.getJvmRoute(); 174 if (jvmRoute != null) 175 { 176 sessionId += '.' + jvmRoute; 177 } 178 179 session.setValid(true); 180 181 session.setId(sessionId); 182 183 return session; 184 } 185 186 191 public String getJvmRouteId(String id) 192 { 193 String sessid = null; 194 if (id != null) 195 { 196 if (this.getJvmRoute() != null) 197 { 198 if (!this.getJvmRoute().equals(id.substring(id.indexOf('.') + 1, id.length()))) 199 { 200 sessid = id.substring(0, id.indexOf('.') + 1) + this.getJvmRoute(); 201 log.debug("JvmRoute id is :" + sessid); 202 } 203 else 204 { 205 return id; 206 } 207 } 208 } 209 return sessid; 210 } 211 212 217 public void setSessionCookie(String sessionId) 218 { 219 HttpServletResponse response = (HttpServletResponse ) ClusteredSessionValve.responseThreadLocal.get(); 220 setNewSessionCookie(sessionId, response); 221 } 222 223 public void setNewSessionCookie(String sessionId, HttpServletResponse response) 224 { 225 if (response != null) 226 { 227 Context context = (Context) container; 228 if (context.getCookies()) 229 { 230 Cookie newCookie = new Cookie (Globals.SESSION_COOKIE_NAME, sessionId); 232 if (log.isDebugEnabled()) 233 { 234 log.debug("Setting cookie with session id:" + sessionId + " & name:" + Globals.SESSION_COOKIE_NAME); 235 } 236 newCookie.setMaxAge(-1); 237 newCookie.setPath(context.getPath()); 238 response.addCookie(newCookie); 239 } 240 } 241 } 242 243 249 public Session findSession(String id) throws IOException 250 { 251 ClusteredSessionCMP session = null; 252 253 if (id == null) 254 { 255 return null; 256 } 257 258 log.debug("Looking for session with id=" + id); 259 260 if (useLocalCache) 261 { 262 synchronized (sessions) 263 { 264 session = (ClusteredSessionCMP) sessions.get(id); 266 } 267 268 if (session == null && this.getJvmRoute() != null) 269 { 270 String key = getJvmRouteId(id); 271 synchronized (sessions) 272 { 273 session = (ClusteredSessionCMP) sessions.get(key); 275 } 276 277 if (session != null) 279 { 280 setSessionCookie(session.getId()); 282 } 283 } 284 285 if (session == null) 287 { 288 session = loadSession(id); 289 290 if (session == null && this.getJvmRoute() != null) 291 { 292 session = loadSession(getJvmRouteId(id)); 293 } 294 if (session != null) 296 { 297 300 if (this.getJvmRoute() != null) 301 { 302 String sessionid = getJvmRouteId(id); 303 304 session.setId(sessionid); 306 307 setSessionCookie(sessionid); 309 310 } 311 else 312 { 313 log.debug("Found in distributed store - adding to local store"); 315 add(session); 316 } 317 } 318 } 319 } 320 else 321 { 322 session = loadSession(id); 324 325 if (session == null && this.getJvmRoute() != null) 327 { 328 String sessionId = this.getJvmRouteId(id); 329 330 session = loadSession(sessionId); 331 332 if (session != null) 333 { 334 session.setId(sessionId); 335 setSessionCookie(sessionId); 336 id = sessionId; 337 } 338 } 339 340 if (session != null) 343 { 344 synchronized (sessions) 345 { 346 sessions.put(id, session); 347 } 348 } 349 } 350 351 if (session != null) 352 { 353 log.debug("Found"); 354 } 355 return session; 356 } 357 358 363 public void add(Session session) 364 { 365 if (session == null) 366 { 367 return; 368 } 369 370 if (!session.isValid()) 371 { 372 log.error("Cannot add session with id=" + session.getId() + " because it is invalid"); 373 return; 374 } 375 376 if (session instanceof ClusteredSessionCMP) 378 { 379 synchronized (sessions) 380 { 381 sessions.put(session.getId(), session); 383 384 try 385 { 386 storeSession(session); 388 } 389 catch (Exception e) 390 { 391 log.error("Adding a session to the clustered store failed", e); 392 } 393 log.debug("Session with id=" + session.getId() + " added"); 394 } 395 } 396 else 397 { 398 throw new IllegalArgumentException ("You can only add ClusteredSessionCMPs to this Manager"); 399 } 400 } 401 402 407 public void remove(Session session) 408 { 409 if (session == null) 410 { 411 return; 412 } 413 synchronized (sessions) 414 { 415 try 416 { 417 removeSession(session.getId()); 419 } 420 catch (Exception e) 421 { 422 log.warn("Removing a session from the clustered store failed", e); 423 } 424 sessions.remove(session.getId()); 426 log.debug("Session with id=" + session.getId() + " removed"); 427 } 428 } 429 430 435 public void removeLocal(Session session) 436 { 437 if (session == null) 438 { 439 return; 440 } 441 synchronized (sessions) 442 { 443 sessions.remove(session.getId()); 444 } 445 } 446 447 452 public void removeLocal(String id) 453 { 454 if (id == null) 455 { 456 return; 457 } 458 synchronized (sessions) 459 { 460 sessions.remove(id); 461 } 462 } 463 464 465 protected void recycle(Session session) 466 { 467 } 469 470 475 public String getInfo() 476 { 477 return info; 478 } 479 480 485 public void start() throws LifecycleException 486 { 487 startManager(); 488 } 489 490 495 public void stop() throws LifecycleException 496 { 497 stopManager(); 498 } 499 500 510 protected void startManager() throws LifecycleException 511 { 512 log.info("Starting"); 513 514 if (started) 516 throw new LifecycleException 517 (sm.getString("standardManager.alreadyStarted")); 518 lifecycle.fireLifecycleEvent(START_EVENT, null); 519 started = true; 520 521 try 523 { 524 MBeanServer server = MBeanServerLocator.locateJBoss(); 525 server.registerMBean(this, objectName); 526 } 527 catch (Exception e) 528 { 529 log.error("Could not register ClusterManagerMBean to MBeanServer", e); 530 } 531 } 532 533 542 protected void stopManager() throws LifecycleException 543 { 544 log.info("Stopping"); 545 546 if (!started) 548 throw new LifecycleException 549 (sm.getString("standardManager.notStarted")); 550 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 551 started = false; 552 553 try 555 { 556 MBeanServer server = MBeanServerLocator.locateJBoss(); 557 server.unregisterMBean(objectName); 558 } 559 catch (Exception e) 560 { 561 log.error("Could not unregister ClusterManagerMBean from MBeanServer", e); 562 } 563 } 564 565 568 public void load() throws ClassNotFoundException , IOException 569 { 570 } 572 573 576 public void unload() throws IOException 577 { 578 } 580 581 585 public void run() 586 { 587 } 589 591 596 private String getNextId() 597 { 598 return proxy.getSessionId(); 599 } 600 601 606 public boolean storeSession(Session session) 607 { 608 if (session == null) 609 { 610 return false; 611 } 612 if (session.isValid()) 613 { 614 ClusteredSessionCMP cmpSession = (ClusteredSessionCMP) session; 616 cmpSession.passivate(); 617 618 if (log.isDebugEnabled()) 619 { 620 log.debug("Replicating session with id " + session.getId()); 621 } 622 623 if (!cmpSession.isReplicationTypeAlreadySet()) 624 cmpSession.setReplicationTypeForSession(this.replicationType); 626 proxy.setHttpSession(session.getId(), (SerializableHttpSession) session); 627 } 628 return true; 629 } 630 631 637 protected ClusteredSessionCMP loadSession(String id) 638 { 639 ClusteredSessionCMP session = null; 640 641 if (id == null) 642 { 643 return null; 644 } 645 646 try 647 { 648 651 ClassLoader ctxCL = super.getContainer().getLoader().getClassLoader(); 652 session = (ClusteredSessionCMP) proxy.getHttpSession(id, ctxCL); 653 654 if (session != null) 655 { 656 session.initAfterLoad(this); 658 } 659 660 } 661 catch (EJBException e) 662 { 663 log.debug("Loading a session out of the clustered store failed", e); 665 } 666 667 return session; 668 } 669 670 675 protected void removeSession(String id) 676 { 677 if (id == null) 678 { 679 return; 680 } 681 try 682 { 683 proxy.removeHttpSession(id); 684 } 685 catch (EJBException e) 686 { 687 log.debug("Removing a session out of the clustered store failed", e); 689 } 690 } 691 692 695 public void processExpires() 696 { 697 long timeNow = System.currentTimeMillis(); 699 700 Session sessions[] = findSessions(); 702 703 log.debug("Looking for sessions that have expired"); 704 705 for (int i = 0; i < sessions.length; ++i) 706 { 707 ClusteredSessionCMP session = (ClusteredSessionCMP) sessions[i]; 708 709 if (!session.isValid()) 711 { 712 continue; 713 } 714 715 int maxInactiveInterval = session.getMaxInactiveInterval(); 717 718 if (maxInactiveInterval < 0) 720 { 721 continue; 722 } 723 724 int timeIdle = 726 (int) ((timeNow - session.getLastAccessedTime()) / 1000L); 727 728 if (timeIdle >= maxInactiveInterval) 730 { 731 try 732 { 733 log.debug("Session with id = " + session.getId() + " has expired on local node"); 734 ClusteredSessionCMP clusteredSession = loadSession(session.getId()); 737 if (clusteredSession != null) 738 { 739 int timeIdleCluster = 740 (int) ((timeNow - clusteredSession.getLastAccessedTime()) / 1000L); 741 if (timeIdleCluster < maxInactiveInterval) 742 { 743 log.debug("Session " + session.getId() + " has only expired on local node but is alive on another node - removing only from local store"); 744 removeLocal(session); 747 continue; 748 } 749 750 log.debug("Session " + session.getId() + " has also expired on all other nodes - removing globally"); 751 } 752 753 754 session.expire(); 756 } 757 catch (Throwable t) 758 { 759 log.error("Problems while expiring session with id = " + session.getId(), t); 760 } 761 } 762 } 763 } 764 765 766 } 767 | Popular Tags |