1 17 18 19 package org.apache.catalina.session; 20 21 import java.beans.PropertyChangeEvent ; 22 import java.beans.PropertyChangeListener ; 23 import java.io.IOException ; 24 import java.security.AccessController ; 25 import java.security.PrivilegedActionException ; 26 import java.security.PrivilegedExceptionAction ; 27 import org.apache.catalina.Container; 28 import org.apache.catalina.Context; 29 import org.apache.catalina.Lifecycle; 30 import org.apache.catalina.LifecycleException; 31 import org.apache.catalina.LifecycleListener; 32 import org.apache.catalina.Session; 33 import org.apache.catalina.Store; 34 import org.apache.catalina.util.LifecycleSupport; 35 36 import org.apache.catalina.security.SecurityUtil; 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 52 53 public abstract class PersistentManagerBase 54 extends ManagerBase 55 implements Lifecycle, PropertyChangeListener { 56 57 private static Log log = LogFactory.getLog(PersistentManagerBase.class); 58 59 61 private class PrivilegedStoreClear 62 implements PrivilegedExceptionAction { 63 64 PrivilegedStoreClear() { 65 } 66 67 public Object run() throws Exception { 68 store.clear(); 69 return null; 70 } 71 } 72 73 private class PrivilegedStoreRemove 74 implements PrivilegedExceptionAction { 75 76 private String id; 77 78 PrivilegedStoreRemove(String id) { 79 this.id = id; 80 } 81 82 public Object run() throws Exception { 83 store.remove(id); 84 return null; 85 } 86 } 87 88 private class PrivilegedStoreLoad 89 implements PrivilegedExceptionAction { 90 91 private String id; 92 93 PrivilegedStoreLoad(String id) { 94 this.id = id; 95 } 96 97 public Object run() throws Exception { 98 return store.load(id); 99 } 100 } 101 102 private class PrivilegedStoreSave 103 implements PrivilegedExceptionAction { 104 105 private Session session; 106 107 PrivilegedStoreSave(Session session) { 108 this.session = session; 109 } 110 111 public Object run() throws Exception { 112 store.save(session); 113 return null; 114 } 115 } 116 117 private class PrivilegedStoreKeys 118 implements PrivilegedExceptionAction { 119 120 PrivilegedStoreKeys() { 121 } 122 123 public Object run() throws Exception { 124 return store.keys(); 125 } 126 } 127 128 130 131 134 private static final String info = "PersistentManagerBase/1.1"; 135 136 137 140 protected LifecycleSupport lifecycle = new LifecycleSupport(this); 141 142 143 146 protected int maxActiveSessions = -1; 147 148 149 152 private static String name = "PersistentManagerBase"; 153 154 155 158 protected boolean started = false; 159 160 161 164 protected Store store = null; 165 166 167 171 protected boolean saveOnRestart = true; 172 173 174 178 protected int maxIdleBackup = -1; 179 180 181 186 protected int minIdleSwap = -1; 187 188 193 protected int maxIdleSwap = -1; 194 195 196 199 protected int rejectedSessions = 0; 200 201 202 205 protected long processingTime = 0; 206 207 208 210 211 212 213 214 219 public int getMaxIdleBackup() { 220 221 return maxIdleBackup; 222 223 } 224 225 226 246 public void setMaxIdleBackup (int backup) { 247 248 if (backup == this.maxIdleBackup) 249 return; 250 int oldBackup = this.maxIdleBackup; 251 this.maxIdleBackup = backup; 252 support.firePropertyChange("maxIdleBackup", 253 new Integer (oldBackup), 254 new Integer (this.maxIdleBackup)); 255 256 } 257 258 259 263 public int getMaxIdleSwap() { 264 265 return maxIdleSwap; 266 267 } 268 269 270 274 public void setMaxIdleSwap(int max) { 275 276 if (max == this.maxIdleSwap) 277 return; 278 int oldMaxIdleSwap = this.maxIdleSwap; 279 this.maxIdleSwap = max; 280 support.firePropertyChange("maxIdleSwap", 281 new Integer (oldMaxIdleSwap), 282 new Integer (this.maxIdleSwap)); 283 284 } 285 286 287 292 public int getMinIdleSwap() { 293 294 return minIdleSwap; 295 296 } 297 298 299 304 public void setMinIdleSwap(int min) { 305 306 if (this.minIdleSwap == min) 307 return; 308 int oldMinIdleSwap = this.minIdleSwap; 309 this.minIdleSwap = min; 310 support.firePropertyChange("minIdleSwap", 311 new Integer (oldMinIdleSwap), 312 new Integer (this.minIdleSwap)); 313 314 } 315 316 317 325 public void setContainer(Container container) { 326 327 if ((this.container != null) && (this.container instanceof Context)) 329 ((Context) this.container).removePropertyChangeListener(this); 330 331 super.setContainer(container); 333 334 if ((this.container != null) && (this.container instanceof Context)) { 336 setMaxInactiveInterval 337 ( ((Context) this.container).getSessionTimeout()*60 ); 338 ((Context) this.container).addPropertyChangeListener(this); 339 } 340 341 } 342 343 344 349 public String getInfo() { 350 351 return (info); 352 353 } 354 355 356 362 public boolean isLoaded( String id ){ 363 try { 364 if ( super.findSession(id) != null ) 365 return true; 366 } catch (IOException e) { 367 log.error("checking isLoaded for id, " + id + ", "+e.getMessage(), e); 368 } 369 return false; 370 } 371 372 373 377 public int getMaxActiveSessions() { 378 379 return (this.maxActiveSessions); 380 381 } 382 383 384 390 public void setMaxActiveSessions(int max) { 391 392 int oldMaxActiveSessions = this.maxActiveSessions; 393 this.maxActiveSessions = max; 394 support.firePropertyChange("maxActiveSessions", 395 new Integer (oldMaxActiveSessions), 396 new Integer (this.maxActiveSessions)); 397 398 } 399 400 401 406 public int getRejectedSessions() { 407 return rejectedSessions; 408 } 409 410 411 public void setRejectedSessions(int rejectedSessions) { 412 this.rejectedSessions = rejectedSessions; 413 } 414 415 418 public String getName() { 419 420 return (name); 421 422 } 423 424 425 428 protected boolean isStarted() { 429 430 return started; 431 432 } 433 434 435 438 protected void setStarted(boolean started) { 439 440 this.started = started; 441 442 } 443 444 445 451 public void setStore(Store store) { 452 this.store = store; 453 store.setManager(this); 454 455 } 456 457 458 462 public Store getStore() { 463 464 return (this.store); 465 466 } 467 468 469 470 474 public boolean getSaveOnRestart() { 475 476 return saveOnRestart; 477 478 } 479 480 481 490 public void setSaveOnRestart(boolean saveOnRestart) { 491 492 if (saveOnRestart == this.saveOnRestart) 493 return; 494 495 boolean oldSaveOnRestart = this.saveOnRestart; 496 this.saveOnRestart = saveOnRestart; 497 support.firePropertyChange("saveOnRestart", 498 new Boolean (oldSaveOnRestart), 499 new Boolean (this.saveOnRestart)); 500 501 } 502 503 504 506 507 510 public void clearStore() { 511 512 if (store == null) 513 return; 514 515 try { 516 if (SecurityUtil.isPackageProtectionEnabled()){ 517 try{ 518 AccessController.doPrivileged(new PrivilegedStoreClear()); 519 }catch(PrivilegedActionException ex){ 520 Exception exception = ex.getException(); 521 log.error("Exception clearing the Store: " + exception); 522 exception.printStackTrace(); 523 } 524 } else { 525 store.clear(); 526 } 527 } catch (IOException e) { 528 log.error("Exception clearing the Store: " + e); 529 e.printStackTrace(); 530 } 531 532 } 533 534 535 538 public void processExpires() { 539 540 long timeNow = System.currentTimeMillis(); 541 Session sessions[] = findSessions(); 542 int expireHere = 0 ; 543 if(log.isDebugEnabled()) 544 log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length); 545 for (int i = 0; i < sessions.length; i++) { 546 if (!sessions[i].isValid()) { 547 expiredSessions++; 548 expireHere++; 549 } 550 } 551 processPersistenceChecks(); 552 if ((getStore() != null) && (getStore() instanceof StoreBase)) { 553 ((StoreBase) getStore()).processExpires(); 554 } 555 556 long timeEnd = System.currentTimeMillis(); 557 if(log.isDebugEnabled()) 558 log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere); 559 processingTime += (timeEnd - timeNow); 560 561 } 562 563 564 568 public void processPersistenceChecks() { 569 570 processMaxIdleSwaps(); 571 processMaxActiveSwaps(); 572 processMaxIdleBackups(); 573 574 } 575 576 577 590 public Session findSession(String id) throws IOException { 591 592 Session session = super.findSession(id); 593 if (session != null) 594 return (session); 595 596 session = swapIn(id); 598 return (session); 599 600 } 601 602 608 public void removeSuper(Session session) { 609 super.remove (session); 610 } 611 612 622 public void load() { 623 624 sessions.clear(); 626 627 if (store == null) 628 return; 629 630 String [] ids = null; 631 try { 632 if (SecurityUtil.isPackageProtectionEnabled()){ 633 try{ 634 ids = (String []) 635 AccessController.doPrivileged(new PrivilegedStoreKeys()); 636 }catch(PrivilegedActionException ex){ 637 Exception exception = ex.getException(); 638 log.error("Exception in the Store during load: " 639 + exception); 640 exception.printStackTrace(); 641 } 642 } else { 643 ids = store.keys(); 644 } 645 } catch (IOException e) { 646 log.error("Can't load sessions from store, " + e.getMessage(), e); 647 return; 648 } 649 650 int n = ids.length; 651 if (n == 0) 652 return; 653 654 if (log.isDebugEnabled()) 655 log.debug(sm.getString("persistentManager.loading", String.valueOf(n))); 656 657 for (int i = 0; i < n; i++) 658 try { 659 swapIn(ids[i]); 660 } catch (IOException e) { 661 log.error("Failed load session from store, " + e.getMessage(), e); 662 } 663 664 } 665 666 667 673 public void remove(Session session) { 674 675 super.remove (session); 676 677 if (store != null){ 678 removeSession(session.getIdInternal()); 679 } 680 } 681 682 683 689 protected void removeSession(String id){ 690 try { 691 if (SecurityUtil.isPackageProtectionEnabled()){ 692 try{ 693 AccessController.doPrivileged(new PrivilegedStoreRemove(id)); 694 }catch(PrivilegedActionException ex){ 695 Exception exception = ex.getException(); 696 log.error("Exception in the Store during removeSession: " 697 + exception); 698 exception.printStackTrace(); 699 } 700 } else { 701 store.remove(id); 702 } 703 } catch (IOException e) { 704 log.error("Exception removing session " + e.getMessage()); 705 e.printStackTrace(); 706 } 707 } 708 709 718 public void unload() { 719 720 if (store == null) 721 return; 722 723 Session sessions[] = findSessions(); 724 int n = sessions.length; 725 if (n == 0) 726 return; 727 728 if (log.isDebugEnabled()) 729 log.debug(sm.getString("persistentManager.unloading", 730 String.valueOf(n))); 731 732 for (int i = 0; i < n; i++) 733 try { 734 swapOut(sessions[i]); 735 } catch (IOException e) { 736 ; } 738 739 } 740 741 742 744 745 752 protected Session swapIn(String id) throws IOException { 753 754 if (store == null) 755 return null; 756 757 Session session = null; 758 try { 759 if (SecurityUtil.isPackageProtectionEnabled()){ 760 try{ 761 session = (Session) 762 AccessController.doPrivileged(new PrivilegedStoreLoad(id)); 763 }catch(PrivilegedActionException ex){ 764 Exception exception = ex.getException(); 765 log.error("Exception in the Store during swapIn: " 766 + exception); 767 if (exception instanceof IOException ){ 768 throw (IOException )exception; 769 } else if (exception instanceof ClassNotFoundException ) { 770 throw (ClassNotFoundException )exception; 771 } 772 } 773 } else { 774 session = store.load(id); 775 } 776 } catch (ClassNotFoundException e) { 777 log.error(sm.getString("persistentManager.deserializeError", id, e)); 778 throw new IllegalStateException 779 (sm.getString("persistentManager.deserializeError", id, e)); 780 } 781 782 if (session == null) 783 return (null); 784 785 if (!session.isValid()) { 786 log.error("session swapped in is invalid or expired"); 787 session.expire(); 788 removeSession(id); 789 return (null); 790 } 791 792 if(log.isDebugEnabled()) 793 log.debug(sm.getString("persistentManager.swapIn", id)); 794 795 session.setManager(this); 796 ((StandardSession)session).tellNew(); 798 add(session); 799 ((StandardSession)session).activate(); 800 session.endAccess(); 801 802 return (session); 803 804 } 805 806 807 815 protected void swapOut(Session session) throws IOException { 816 817 if (store == null || !session.isValid()) { 818 return; 819 } 820 821 ((StandardSession)session).passivate(); 822 writeSession(session); 823 super.remove(session); 824 session.recycle(); 825 826 } 827 828 829 834 protected void writeSession(Session session) throws IOException { 835 836 if (store == null || !session.isValid()) { 837 return; 838 } 839 840 try { 841 if (SecurityUtil.isPackageProtectionEnabled()){ 842 try{ 843 AccessController.doPrivileged(new PrivilegedStoreSave(session)); 844 }catch(PrivilegedActionException ex){ 845 Exception exception = ex.getException(); 846 log.error("Exception in the Store during writeSession: " 847 + exception); 848 exception.printStackTrace(); 849 } 850 } else { 851 store.save(session); 852 } 853 } catch (IOException e) { 854 log.error(sm.getString 855 ("persistentManager.serializeError", session.getIdInternal(), e)); 856 throw e; 857 } 858 859 } 860 861 862 864 865 870 public void addLifecycleListener(LifecycleListener listener) { 871 872 lifecycle.addLifecycleListener(listener); 873 874 } 875 876 877 881 public LifecycleListener[] findLifecycleListeners() { 882 883 return lifecycle.findLifecycleListeners(); 884 885 } 886 887 888 893 public void removeLifecycleListener(LifecycleListener listener) { 894 895 lifecycle.removeLifecycleListener(listener); 896 897 } 898 899 900 908 public void start() throws LifecycleException { 909 910 if (started) { 912 log.info(sm.getString("standardManager.alreadyStarted")); 913 return; 914 } 915 if( ! initialized ) 916 init(); 917 918 lifecycle.fireLifecycleEvent(START_EVENT, null); 919 started = true; 920 921 if (log.isDebugEnabled()) 923 log.debug("Force random number initialization starting"); 924 String dummy = generateSessionId(); 925 if (log.isDebugEnabled()) 926 log.debug("Force random number initialization completed"); 927 928 if (store == null) 929 log.error("No Store configured, persistence disabled"); 930 else if (store instanceof Lifecycle) 931 ((Lifecycle)store).start(); 932 933 } 934 935 936 944 public void stop() throws LifecycleException { 945 946 if (log.isDebugEnabled()) 947 log.debug("Stopping"); 948 949 if (!isStarted()) { 951 log.info(sm.getString("standardManager.notStarted")); 952 return; 953 } 954 955 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 956 setStarted(false); 957 958 if (getStore() != null && saveOnRestart) { 959 unload(); 960 } else { 961 Session sessions[] = findSessions(); 963 for (int i = 0; i < sessions.length; i++) { 964 StandardSession session = (StandardSession) sessions[i]; 965 if (!session.isValid()) 966 continue; 967 session.expire(); 968 } 969 } 970 971 if (getStore() != null && getStore() instanceof Lifecycle) 972 ((Lifecycle)getStore()).stop(); 973 974 this.random = null; 976 977 if( initialized ) 978 destroy(); 979 980 } 981 982 983 985 986 991 public void propertyChange(PropertyChangeEvent event) { 992 993 if (!(event.getSource() instanceof Context)) 995 return; 996 Context context = (Context) event.getSource(); 997 998 if (event.getPropertyName().equals("sessionTimeout")) { 1000 try { 1001 setMaxInactiveInterval 1002 ( ((Integer ) event.getNewValue()).intValue()*60 ); 1003 } catch (NumberFormatException e) { 1004 log.error(sm.getString("standardManager.sessionTimeout", 1005 event.getNewValue().toString())); 1006 } 1007 } 1008 1009 } 1010 1011 1012 1014 1015 1018 protected void processMaxIdleSwaps() { 1019 1020 if (!isStarted() || maxIdleSwap < 0) 1021 return; 1022 1023 Session sessions[] = findSessions(); 1024 long timeNow = System.currentTimeMillis(); 1025 1026 if (maxIdleSwap >= 0) { 1030 for (int i = 0; i < sessions.length; i++) { 1031 StandardSession session = (StandardSession) sessions[i]; 1032 if (!session.isValid()) 1033 continue; 1034 int timeIdle = (int) ((timeNow - session.getLastAccessedTime()) / 1000L); 1036 if (timeIdle > maxIdleSwap && timeIdle > minIdleSwap) { 1037 if (log.isDebugEnabled()) 1038 log.debug(sm.getString 1039 ("persistentManager.swapMaxIdle", 1040 session.getIdInternal(), new Integer (timeIdle))); 1041 try { 1042 swapOut(session); 1043 } catch (IOException e) { 1044 ; } 1046 } 1047 } 1048 } 1049 1050 } 1051 1052 1053 1056 protected void processMaxActiveSwaps() { 1057 1058 if (!isStarted() || getMaxActiveSessions() < 0) 1059 return; 1060 1061 Session sessions[] = findSessions(); 1062 1063 if (getMaxActiveSessions() >= sessions.length) 1065 return; 1066 1067 if(log.isDebugEnabled()) 1068 log.debug(sm.getString 1069 ("persistentManager.tooManyActive", 1070 new Integer (sessions.length))); 1071 1072 int toswap = sessions.length - getMaxActiveSessions(); 1073 long timeNow = System.currentTimeMillis(); 1074 1075 for (int i = 0; i < sessions.length && toswap > 0; i++) { 1076 int timeIdle = (int) ((timeNow - sessions[i].getLastAccessedTime()) / 1000L); 1078 if (timeIdle > minIdleSwap) { 1079 if(log.isDebugEnabled()) 1080 log.debug(sm.getString 1081 ("persistentManager.swapTooManyActive", 1082 sessions[i].getIdInternal(), new Integer (timeIdle))); 1083 try { 1084 swapOut(sessions[i]); 1085 } catch (IOException e) { 1086 ; } 1088 toswap--; 1089 } 1090 } 1091 1092 } 1093 1094 1095 1098 protected void processMaxIdleBackups() { 1099 1100 if (!isStarted() || maxIdleBackup < 0) 1101 return; 1102 1103 Session sessions[] = findSessions(); 1104 long timeNow = System.currentTimeMillis(); 1105 1106 if (maxIdleBackup >= 0) { 1108 for (int i = 0; i < sessions.length; i++) { 1109 StandardSession session = (StandardSession) sessions[i]; 1110 if (!session.isValid()) 1111 continue; 1112 int timeIdle = (int) ((timeNow - session.getLastAccessedTime()) / 1000L); 1114 if (timeIdle > maxIdleBackup) { 1115 if (log.isDebugEnabled()) 1116 log.debug(sm.getString 1117 ("persistentManager.backupMaxIdle", 1118 session.getIdInternal(), new Integer (timeIdle))); 1119 1120 try { 1121 writeSession(session); 1122 } catch (IOException e) { 1123 ; } 1125 } 1126 } 1127 } 1128 1129 } 1130 1131} 1132 | Popular Tags |