1 23 24 package com.sun.ejb.base.sfsb.store; 25 26 import java.io.BufferedInputStream ; 27 import java.io.BufferedOutputStream ; 28 import java.io.File ; 29 import java.io.FileInputStream ; 30 import java.io.FileOutputStream ; 31 import java.io.IOException ; 32 import java.io.ObjectInputStream ; 33 import java.io.ObjectOutputStream ; 34 import java.io.PrintWriter ; 35 import java.io.StringWriter ; 36 37 import java.util.HashMap ; 38 import java.util.Iterator ; 39 import java.util.Map ; 40 41 import java.util.logging.*; 42 43 import com.sun.ejb.spi.monitorable.sfsb.MonitorableSFSBStore; 44 45 import com.sun.ejb.spi.stats.MonitorableSFSBStoreManager; 46 47 import com.sun.ejb.spi.sfsb.store.SFSBBeanState; 48 import com.sun.ejb.spi.sfsb.store.SFSBStoreManager; 49 import com.sun.ejb.spi.sfsb.store.SFSBStoreManagerException; 50 51 import com.sun.logging.*; 52 53 59 60 public class FileStoreManager 61 implements SFSBStoreManager, MonitorableSFSBStoreManager 62 { 63 protected static Logger _logger = 64 LogDomains.getLogger(LogDomains.EJB_LOGGER); 65 66 protected String clusterId = ""; 67 protected long containerId; 68 69 protected File baseDir; 70 protected String storeName; 71 72 protected int passivationTimeoutInSeconds; 73 74 private int loadCount; 75 private int loadSuccessCount; 76 private int loadErrorCount; 77 private int storeCount; 78 private int storeSuccessCount; 79 private int storeErrorCount; 80 private int expiredSessionCount; 81 82 private boolean shutdown; 83 84 private Level TRACE_LEVEL = Level.FINE; 85 86 private int gracePeriodInSeconds; 87 88 91 public FileStoreManager() { 92 } 93 94 95 96 97 98 public void checkpointSave(SFSBBeanState beanState) 99 throws SFSBStoreManagerException 100 { 101 saveState(beanState, false); 102 if (_logger.isLoggable(TRACE_LEVEL)) { 103 _logger.log(TRACE_LEVEL, storeName + "Checkpoint saved: " 104 + beanState.getId()); 105 } 106 } 107 108 public SFSBBeanState createSFSBBeanState(Object sessionId, 109 long lastAccess, boolean isNew, byte[] state) 110 { 111 return new SFSBBeanState(clusterId, containerId, 112 sessionId, lastAccess, isNew, state, this); 113 } 114 115 public SFSBBeanState getState(Object sessionKey) { 116 117 String fileName = sessionKey.toString(); 118 SFSBBeanState beanState = null; 119 120 if(_logger.isLoggable(TRACE_LEVEL)) { 121 _logger.log(TRACE_LEVEL, storeName + "Attempting to load session: " 122 + sessionKey); 123 } 124 125 File file = new File (baseDir, fileName); 126 if (file.exists()) { 127 int dataSize = (int) file.length(); 128 byte[] data = new byte[dataSize]; 129 BufferedInputStream bis = null; 130 FileInputStream fis = null; 131 try { 132 loadCount++; 133 fis = new FileInputStream (file); 134 bis = new BufferedInputStream (fis); 135 int offset = 0; 136 for (int toRead = dataSize; toRead > 0; ) { 137 int count = bis.read(data, offset, toRead); 138 offset += count; 139 toRead -= count; 140 } 141 142 beanState = new SFSBBeanState("", -1, sessionKey, -1, 143 false, data, this); 144 145 loadSuccessCount++; 146 if(_logger.isLoggable(TRACE_LEVEL)) { 147 _logger.log(TRACE_LEVEL, storeName 148 + " Successfully loaded session: " + sessionKey); 149 } 150 } catch (Exception ex) { 151 loadErrorCount++; 152 _logger.log(Level.WARNING, 153 "ejb.sfsb_storemgr_loadstate_failed", 154 new Object [] {fileName}); 155 _logger.log(Level.WARNING, 156 "ejb.sfsb_storemgr_loadstate_exception", ex); 157 } finally { 158 try { 159 bis.close(); 160 } catch (Exception ex) { 161 _logger.log(Level.FINEST, storeName + " Error while " 162 + "closing buffered input stream", ex); 163 } 164 try { 165 fis.close(); 166 } catch (Exception ex) { 167 _logger.log(Level.FINEST, storeName + " Error while " 168 + "closing file input stream", ex); 169 } 170 } 171 } else { 172 if(_logger.isLoggable(TRACE_LEVEL)) { 173 _logger.log(Level.WARNING, storeName + "Could not find passivated " 174 + "file for: " + sessionKey); 175 } 176 } 177 return beanState; 178 } 179 180 public void initSessionStore(Map storeEnv) { 181 182 this.storeName = (String ) storeEnv.get( 183 FileStoreManagerConstants.STORE_MANAGER_NAME); 184 try { 185 Long cId = (Long ) storeEnv.get( 186 FileStoreManagerConstants.CONTAINER_ID); 187 this.containerId = cId.longValue(); 188 } catch (Exception ex) { 189 _logger.log(Level.WARNING, "Couldn't get containerID", ex); 190 } 191 192 String baseDirName = (String ) storeEnv.get( 193 FileStoreManagerConstants.PASSIVATION_DIRECTORY_NAME); 194 195 this.baseDir = new File (baseDirName); 196 197 try { 198 Integer sessionTimeout = (Integer ) storeEnv.get( 199 FileStoreManagerConstants.SESSION_TIMEOUT_IN_SECONDS); 200 if (sessionTimeout != null) { 201 this.passivationTimeoutInSeconds = sessionTimeout.intValue(); 202 } 203 } catch (Exception ex) { 204 _logger.log(Level.WARNING, "Couldn't get session timeout", ex); 205 } 206 207 try { 208 Integer graceTimeout = (Integer ) storeEnv.get( 209 FileStoreManagerConstants.GRACE_SESSION_TIMEOUT_IN_SECONDS); 210 if (graceTimeout != null) { 211 this.gracePeriodInSeconds = graceTimeout.intValue(); 212 } 213 } catch (Exception ex) { 214 _logger.log(Level.WARNING, "Couldn't get session timeout", ex); 215 } 216 217 try { 218 if ((baseDir.mkdirs() == false) && (!baseDir.isDirectory())) { 219 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_mdirs_failed", 220 new Object [] {baseDirName}); 221 } else { 223 if (_logger.isLoggable(TRACE_LEVEL)) { 224 _logger.log(TRACE_LEVEL, "Successfully Initialized " 225 + "FileStoreManager for: " + storeName); 226 } 227 } 228 } catch (Exception ex) { 229 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_init_failed", 230 new Object [] {baseDirName}); 231 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_init_exception", ex); 232 } 233 234 } 235 236 public void passivateSave(SFSBBeanState beanState) 237 throws SFSBStoreManagerException 238 { 239 saveState(beanState, true); 240 } 241 242 public void remove(Object sessionKey) { 243 try { 244 removeFile(new File (baseDir, sessionKey.toString())); 245 } catch (Exception ex) { 246 _logger.log(Level.WARNING, 247 "ejb.sfsb_storemgr_removestate_failed", 248 new Object [] {sessionKey.toString()}); 249 _logger.log(Level.WARNING, 250 "ejb.sfsb_storemgr_removestate_exception", ex); 251 } 252 } 253 254 public void removeAll() { 255 try { 256 String [] fileNames = baseDir.list(); 257 for (int i=0; i<fileNames.length; i++) { 258 remove(fileNames[i]); 259 } 260 261 if (baseDir.delete() == false) { 262 if (baseDir.exists()) { 263 Object [] params = {baseDir.getAbsolutePath()}; 264 _logger.log(Level.WARNING, 265 "ejb.sfsb_storemgr_removedir_failed", params); 266 } 267 } 268 } catch (Throwable th) { 269 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_removeall_exception", th); 270 } 271 } 272 273 public void removeExpired() { 274 expiredSessionCount += removeExpiredSessions(); 275 } 276 277 public int removeExpiredSessions() { 278 if (passivationTimeoutInSeconds <= 0) { 279 return 0; 280 } 281 long threshold = System.currentTimeMillis() 282 - (passivationTimeoutInSeconds * 1000) 283 - (gracePeriodInSeconds * 1000); 284 int expiredSessions = 0; 285 try { 286 String [] fileNames = baseDir.list(); 287 int size = fileNames.length; 288 for (int i=0; (i<size) && (! shutdown); i++) { 289 File file = new File (baseDir, fileNames[i]); 290 if (file.exists()) { 291 long lastAccessed = file.lastModified(); 292 if (lastAccessed < threshold) { 293 if (! file.delete()) { 294 if (file.exists()) { 295 _logger.log(Level.WARNING, storeName 296 + "Couldn't remove file: " + fileNames[i]); 297 } 298 } else { 299 expiredSessions++; 300 } 301 } 302 } 303 } 304 } catch (Exception ex) { 305 _logger.log(Level.WARNING, storeName + "Exception while getting " 306 + "expired files", ex); 307 } 308 309 return expiredSessions; 310 } 311 312 public void shutdown() { 313 shutdown = true; 314 } 315 316 public void updateLastAccessTime(Object sessionKey, long time) 317 throws SFSBStoreManagerException 318 { 319 String fileName = sessionKey.toString(); 320 try { 321 File file = new File (baseDir, fileName); 322 323 if (file.setLastModified(time) == false) { 324 if (file.exists() == false) { 325 _logger.log(Level.WARNING, storeName 326 + ": Cannot update timsestamp for: " + sessionKey 327 + "; File does not exist"); 328 } else { 329 throw new SFSBStoreManagerException( 330 storeName + ": Cannot update timsestamp for: " + sessionKey); 331 } 332 } 333 } catch (SFSBStoreManagerException sfsbSMEx) { 334 throw sfsbSMEx; 335 } catch (Exception ex) { 336 _logger.log(Level.WARNING, storeName 337 + ": Exception while updating timestamp", ex); 338 throw new SFSBStoreManagerException( 339 "Cannot update timsestamp for: " + sessionKey 340 + "; Got exception: " + ex); 341 } 342 } 343 344 345 346 347 348 public int getCurrentSize() { 349 try { 351 return baseDir.list().length; 352 } catch (Exception ex) { 353 } 354 return 0; 355 } 356 357 public int getLoadCount() { 358 return loadCount; 359 } 360 361 public int getLoadSuccessCount() { 362 return loadSuccessCount; 363 } 364 365 public int getLoadErrorCount() { 366 return loadErrorCount; 367 } 368 369 public int getPassivationCount() { 370 return storeCount; 371 } 372 373 public int getPassivationSuccessCount() { 374 return storeSuccessCount; 375 } 376 377 public int getPassivationErrorCount() { 378 return storeErrorCount; 379 } 380 381 public int getCheckpointCount() { 382 return storeCount; 383 } 384 385 public int getCheckpointSuccessCount() { 386 return storeSuccessCount; 387 } 388 389 public int getCheckpointErrorCount() { 390 return storeErrorCount; 391 } 392 393 public int getExpiredSessionCount() { 394 return expiredSessionCount; 395 } 396 397 398 399 400 401 402 private void saveState(SFSBBeanState beanState, boolean isPassivated) 403 throws SFSBStoreManagerException 404 { 405 406 Object sessionKey = beanState.getId(); 407 String fileName = sessionKey.toString(); 408 409 if(_logger.isLoggable(TRACE_LEVEL)) { 410 _logger.log(TRACE_LEVEL, storeName + " Attempting to save " 411 + "session: " + sessionKey); 412 } 413 File file = null; 414 415 BufferedOutputStream bos = null; 416 FileOutputStream fos = null; 417 418 try { 419 storeCount++; 420 file = new File (baseDir, fileName); 421 if (file.exists()) { 422 if (beanState.isNew()) { 423 _logger.log(Level.WARNING, storeName + " [InternalError] " 424 + "isNew() must be false for: " + sessionKey); 425 } 426 } else { 427 if (beanState.isNew() == false) { 428 _logger.log(Level.WARNING, storeName + " [InternalError] " 429 + "isNew() must be true for: " + sessionKey); 430 } 431 } 432 fos = new FileOutputStream (file); 433 bos = new BufferedOutputStream (fos); 434 byte[] data = beanState.getState(); 435 bos.write(data, 0, data.length); 436 437 storeSuccessCount++; 438 if(_logger.isLoggable(TRACE_LEVEL)) { 439 _logger.log(TRACE_LEVEL, storeName + " Successfully saved " 440 + "session: " + sessionKey); 441 } 442 } catch (Exception ex) { 443 storeErrorCount++; 444 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_savestate_failed", 445 new Object [] {fileName}); 446 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_savestate_exception", ex); 447 try { removeFile(file); } catch (Exception ex1) {} 448 String errMsg = "Could not save session: " + beanState.getId(); 449 throw new SFSBStoreManagerException(errMsg, ex); 450 } finally { 451 try { 452 if (bos != null) bos.close(); 453 } catch (Exception ex) { 454 _logger.log(Level.FINE, "Error while closing buffered output stream", ex); 455 } 456 try { 457 if (fos != null) fos.close(); 458 } catch (Exception ex) { 459 _logger.log(Level.FINE, "Error while closing file output stream", ex); 460 } 461 } 462 } 463 464 private boolean removeFile(final File file) { 465 Boolean status = (Boolean ) java.security.AccessController.doPrivileged( 466 new java.security.PrivilegedAction () { 467 public java.lang.Object run() { 468 return (new Boolean (file.delete())); 469 } 470 } 471 ); 472 473 boolean success = status.booleanValue(); 474 if (!success) { 475 _logger.log(Level.WARNING, "ejb.sfsb_storemgr_removestate_failed", 476 new Object [] {file.getName()}); 477 } else { 478 if(_logger.isLoggable(TRACE_LEVEL)) { 479 _logger.log(TRACE_LEVEL, storeName + " Removed session: " 480 + file.getName()); 481 } 482 } 483 484 return success; 485 } 486 487 public MonitorableSFSBStoreManager getMonitorableSFSBStoreManager() { 488 return this; 489 } 490 491 public long getCurrentStoreSize() { 492 try { 493 return baseDir.list().length; 494 } catch (Exception ex) { 495 } 496 return 0; 497 } 498 499 public void appendStats(StringBuffer sbuf) { 500 } 501 502 public void monitoringLevelChanged(boolean monitoringOn) { 503 } 504 505 } 506 | Popular Tags |