1 9 package org.ozoneDB.core; 10 11 import java.io.*; 12 import java.lang.reflect.Constructor ; 13 import java.util.StringTokenizer ; 14 15 import org.ozoneDB.Database; 16 import org.ozoneDB.DxLib.*; 17 import org.ozoneDB.Setup; 18 import org.ozoneDB.core.admin.AdminManager; 19 import org.ozoneDB.core.dr.DeadlockRecognition; 20 import org.ozoneDB.core.dr.EdgeChasing; 21 import org.ozoneDB.OzoneInterface; 22 import org.ozoneDB.util.*; 23 24 25 36 public final class Env { 37 38 48 public final static boolean selfCheck = true; 49 50 public final static String VERSION = "@version@"; 52 public final static String OS_DIR = "ostab"; 53 public final static String STATE_FILE = "state.properties"; 54 public final static String CONFIG_FILE = "config.properties"; 55 public final static String DATA_DIR = "data" + File.separator; 56 public final static String STATS_DIR = "stats"; 57 58 61 public final static int ACCEPT_THREAD_PRIORITY = Thread.NORM_PRIORITY + 2; 62 63 66 public final static int TRANSACTION_THREAD_PRIORITY = Thread.NORM_PRIORITY; 67 68 public final static int TRANSACTION_MUTEX_PRIORITY = TRANSACTION_THREAD_PRIORITY + 1; 69 70 73 public final static int DEADLOCK_THREAD_PRIORITY = Thread.NORM_PRIORITY; 74 75 78 public final static int SERVER_THREAD_PRIORITY = Thread.NORM_PRIORITY + 2; 79 80 81 83 86 public static Env theEnv; 87 88 protected static OzoneSecurityManager securityManager; 89 90 91 93 protected File databaseDir; 94 95 100 public Setup state; 101 102 105 public Setup config; 106 107 public LogWriter logWriter; 108 109 112 public boolean shuttingdown = false; 113 114 117 protected long totalMemory; 118 119 122 protected long keepMemory; 123 124 127 public Database database; 128 129 private DxBag components; 130 131 public KeyGenerator keyGenerator; 132 133 public AdminManager adminManager; 134 135 public ClassManager classManager; 136 137 public TransactionManager transactionManager; 138 139 public StoreManager storeManager; 140 141 public UserManager userManager; 142 143 protected LocalClientTracker localClientTracker; 144 145 protected GarbageCollector garbageCollector; 146 147 protected InvokeServer invokeServer; 148 149 protected DeadlockThread deadlockThread; 150 151 protected DeadlockRecognition dr; 152 153 154 156 164 public static Env currentEnv() { 165 return theEnv; 166 } 167 168 169 171 180 public Env(String dirName, String debugLevel) throws Exception { 181 if (theEnv != null) { 182 throw new Exception ("ozone environment (Env) already initialized for this VM"); 183 } 184 185 try { 186 theEnv = this; 189 190 databaseDir = new File(dirName + File.separator); 192 if (!databaseDir.isDirectory()) { 193 throw new Exception ("No database found at '" + databaseDir + "'."); 194 } 195 checkJavaVersion(); 196 197 initSetup(); 198 initLogs(debugLevel); 199 200 getLogWriter().newEntry(this, "Ozone version @version@", LogWriter.INFO); 201 getLogWriter().newEntry(this, "Copyright (C) 1997-@year@ The Ozone Database Project", LogWriter.INFO); 202 getLogWriter().newEntry(this, "contains libraries from the Apache Software Foundation", LogWriter.INFO); 203 getLogWriter().newEntry(this, "contains libraries from SUN microsystems", LogWriter.INFO); 204 getLogWriter().newEntry(this, "contains libraries from the W3C", LogWriter.INFO); 205 getLogWriter().newEntry(this, "contains libraries from Exoffice, Inc.", LogWriter.INFO); 206 getLogWriter().newEntry(this, "contains libraries (JavaClass) from Markus Dahm ", LogWriter.INFO); 207 getLogWriter().newEntry(this, "Copyright (C) under owner's respective terms.", LogWriter.INFO); 208 209 if (System.getSecurityManager() == null) { 210 securityManager = new OzoneSecurityManager(); 211 System.setSecurityManager(securityManager); 212 } 213 214 calcMemory(); 215 216 components = new DxArrayBag(16); 217 218 localClientTracker = new LocalClientTracker(); 219 220 garbageCollector = new GarbageCollector(this); 221 components.add(garbageCollector); 222 garbageCollector.startup(); 223 224 keyGenerator = new KeyGenerator(this); 225 components.add(keyGenerator); 226 keyGenerator.startup(); 227 228 database = new Database(this); 229 230 classManager = new ClassManager(this); 231 components.add(classManager); 232 classManager.startup(); 233 234 userManager = new UserManager(this); 236 components.add(userManager); 237 userManager.startup(); 238 239 transactionManager = new TransactionManager(this); 240 components.add(transactionManager); 241 transactionManager.startup(); 242 243 String storeClassName = config.stringProperty(Setup.STORE, "org.ozoneDB.core.storage.wizardStore.WizardStore"); 245 Class storeClass = classManager.classForName(storeClassName); 249 if (storeClass == null) { 250 getLogWriter().newEntry(this, "Store not found: " + storeClassName, LogWriter.ERROR); 251 System.exit(1); 252 } 253 Constructor ctor = storeClass.getConstructor(new Class []{Env.class}); 254 storeManager = (StoreManager) ctor.newInstance(new Object []{this}); 255 storeManager.init(this); 256 components.add(storeManager); 257 storeManager.startup(); 258 259 adminManager = new AdminManager(this); 261 components.add(adminManager); 262 adminManager.startup(); 263 } catch (Exception e) { 264 theEnv = null; 265 if (logWriter != null) { 266 logWriter.newEntry(this, "Unable to initialize server.", e, LogWriter.ERROR); 267 } else { 268 System.out.println("Unable to initialize server."); 269 e.printStackTrace(); 270 } 271 throw e; 272 } 273 } 274 275 276 private void checkJavaVersion() throws Exception { 277 String javaVersion = System.getProperty("java.version"); 278 StringTokenizer tokenizer = new StringTokenizer (javaVersion, "."); 279 280 int majorVersion = 0; 281 if (tokenizer.hasMoreTokens()) { 282 majorVersion = Integer.parseInt(tokenizer.nextToken()); 283 } 284 int minorVersion = 0; 285 if (tokenizer.hasMoreTokens()) { 286 minorVersion = Integer.parseInt(tokenizer.nextToken()); 287 } 288 289 if (majorVersion == 1 && minorVersion < 4) { 290 throw new Exception ("Java version 1.4 or higher is required to run the server"); 291 } 292 } 293 294 295 public void shutdown() { 296 shuttingdown = true; 297 try { 298 logWriter.newEntry(this, "shutdown...", LogWriter.INFO); 299 300 if (invokeServer != null) { 306 invokeServer.shutdown(); 307 invokeServer = null; 308 } 309 if (deadlockThread != null) { 310 deadlockThread.stopRunning(); 312 deadlockThread = null; 313 logWriter.newEntry(this, "Deadlock recognition stopped.", LogWriter.INFO); 314 } 315 316 transactionManager.shutdown(); 317 transactionManager = null; 318 319 storeManager.shutdown(); 320 storeManager = null; 321 322 userManager.shutdown(); 323 userManager = null; 324 325 classManager.shutdown(); 326 classManager = null; 327 328 keyGenerator.shutdown(); 329 keyGenerator = null; 330 331 garbageCollector.shutdown(); 332 garbageCollector = null; 333 334 storeSetup(); 335 336 components = null; 337 338 logWriter.newEntry(this, "Halted.", LogWriter.INFO); 339 theEnv = null; 340 } catch (Exception e) { 341 fatalError(null, "Env.shutdown(): " + e.toString(), e); 342 } 343 } 344 345 346 public void startExternalEventProcessing() throws Exception { 347 try { 348 invokeServer = new InvokeServer(this, portNum()); 349 invokeServer.startup(); 350 invokeServer.accept(); 351 logWriter.newEntry(this, "external event processing started", LogWriter.INFO); 352 } catch (Exception e) { 353 logWriter.newEntry(this, 354 "Client port (" + portNum() + ") or admin port (" + adminPortNum() + ") are already in use.", e, 355 LogWriter.ERROR); 356 throw e; 357 } 358 } 359 360 361 public void startDeadlockRecognition() { 362 logWriter.newEntry(this, "deadlock recognition started", LogWriter.INFO); 363 deadlockThread = new DeadlockThread(3000, transactionManager); 364 deadlockThread.setPriority(DEADLOCK_THREAD_PRIORITY); 365 deadlockThread.setDaemon(true); 366 deadlockThread.start(); 367 } 368 369 370 375 protected void initSetup() throws Exception { 376 Setup defaults = new Setup(this); 377 defaults.fillWithOzoneDefaults(); 378 379 FileInputStream configIn = new FileInputStream(new File(databaseDir, CONFIG_FILE)); 380 FileInputStream stateIn = new FileInputStream(new File(databaseDir, STATE_FILE)); 381 try { 382 config = new Setup(this, defaults); 383 config.load(configIn); 384 config.addProperties(System.getProperties(), "ozoneDB."); 385 config.addProperties(System.getProperties(), "org.ozoneDB."); 386 389 state = new Setup(this); 390 state.load(stateIn); 391 } finally { 393 configIn.close(); 394 stateIn.close(); 395 } 396 } 397 398 399 public boolean isComponentStateChanged() { 400 boolean hasChanged = false; 401 402 DxIterator it = components.iterator(); 403 while (it.next() != null) { 404 ServerComponent component = (ServerComponent) it.object(); 405 if (component.hasChanged()) { 406 hasChanged = true; 407 } 408 } 409 return hasChanged; 410 } 411 412 413 416 protected synchronized void storeSetup() { 417 logWriter.newEntry(this, "storeSetup()... ", LogWriter.DEBUG); 418 419 try { 420 DxIterator it = components.iterator(); 422 while (it.next() != null) { 423 ServerComponent component = (ServerComponent) it.object(); 424 if (component.hasChanged()) { 425 logWriter.newEntry(this, " changed component: " + component, LogWriter.DEBUG); 426 component.save(); 427 component.clearChanged(); 428 } 429 } 430 431 OutputStream stateOut = new BufferedOutputStream(new FileOutputStream(new File(databaseDir, STATE_FILE))); 433 OutputStream configOut = new BufferedOutputStream(new FileOutputStream(new File(databaseDir, CONFIG_FILE))); 434 try { 435 state.store(stateOut, "Ozone Server State File.\n#Do not edit!"); 437 438 StringBuffer head = new StringBuffer (1024); 440 head.append("Ozone Server Config File.\n"); 441 head.append("#\n"); 442 head.append("# Do not use comments. This file will be overwritten,\n"); 443 head.append("# if the config changes. See the ozone documentation\n"); 444 head.append("# for details about the properties and their values.\n"); 445 head.append("#\n"); 446 head.append("\n"); 447 head.append("# The below are not set to a default value so they are shown here as exmples \n"); 448 head.append("# of what can be set, see the configuration docs for details \n"); 449 head.append("# "+ Setup.TOTAL_MEMORY + "=16777216" +"\n"); 450 head.append("# "+ Setup.MIN_FREE_MEMORY + "=4194304" +"\n"); 451 config.store(configOut, head.toString()); 452 } finally { 453 stateOut.close(); 454 configOut.close(); 455 } 456 } catch (Exception e) { 457 fatalError(this, "Unable to store server state.", e); 458 } 459 } 460 461 462 469 protected void initLogs(String debugLevelName) throws Exception { 470 471 if (debugLevelName == null) { 472 String defaultLevel = OzoneDebugLevel.INFO_STR; 473 debugLevelName = config.getProperty(Setup.LOG_LEVEL, defaultLevel); 474 } 475 System.out.println("logging level set to " + debugLevelName); 476 logWriter = new LogWriterLog4JImpl(databaseDir, OzoneDebugLevel.toLevel(debugLevelName)); 477 478 } 479 480 483 public void fatalError(Object sender, String msg, Exception e) { 484 logWriter.newEntry(sender, msg, e, LogWriter.ERROR); 485 if (theEnv != null) { 487 theEnv.shutdown(); 488 } 489 System.exit(1); 490 } 491 492 493 public String getDatabaseDir() { 494 return databaseDir.getAbsolutePath() + File.separator; 495 } 496 497 public int dbID() { 498 return config.intProperty(Setup.DB_ID, -1); 499 } 500 501 502 public int portNum() { 503 return config.intProperty(Setup.PORT, -1); 504 } 505 506 507 public int adminPortNum() { 508 return config.intProperty(Setup.ADMIN_PORT, -1); 509 } 510 511 512 515 public DeadlockRecognition deadlockRecognition() { 516 if (dr == null) { 517 dr = new EdgeChasing(this); 518 } 519 return dr; 520 } 521 522 523 527 protected void calcMemory() { 528 Runtime rt = Runtime.getRuntime(); 529 530 totalMemory = config.longProperty(Setup.TOTAL_MEMORY, -1); 532 534 552 if (totalMemory < 0) { 553 logWriter.newEntry(this, "checking memory... ", LogWriter.INFO); 554 try { 555 DxBag bag = new DxArrayBag(); 556 for (; ;) { 557 bag.add(new byte[100000]); 558 } 559 } catch (OutOfMemoryError e) { 560 totalMemory = rt.totalMemory(); 561 } 562 } 563 564 long absoluteMinimumFreeMemoryRequest = config.longProperty(Setup.MIN_FREE_MEMORY, -1); 565 566 if (absoluteMinimumFreeMemoryRequest < 0) { 567 keepMemory = Math.min(4000000L, totalMemory / 10); 568 } else { 569 keepMemory = absoluteMinimumFreeMemoryRequest; 570 } 571 572 rt.gc(); 573 574 logWriter.newEntry(this, " total: " + totalMemory, LogWriter.INFO); 575 logWriter.newEntry(this, " free : " + rt.freeMemory(), LogWriter.INFO); 576 logWriter.newEntry(this, " keep : " + keepMemory, LogWriter.INFO); 577 } 578 579 580 585 public long freeMemory() { 586 Runtime rt = Runtime.getRuntime(); 587 long hiddenMemory = totalMemory - rt.totalMemory(); 588 589 return Math.max(rt.freeMemory() + hiddenMemory - keepMemory, 0); 591 } 592 593 public LogWriter getLogWriter() { 594 return logWriter; 595 } 596 597 public TransactionManager getTransactionManager() { 598 return transactionManager; 599 } 600 601 public Setup getState() { 602 return state; 603 } 604 605 public InvokeServer getInvokeServer() { 606 return invokeServer; 607 } 608 609 public StoreManager getStoreManager() { 610 return storeManager; 611 } 612 613 public UserManager getUserManager() { 614 return userManager; 615 } 616 617 public GarbageCollector getGarbageCollector() { 618 return garbageCollector; 619 } 620 621 public LocalClientTracker getLocalClientTracker() { 622 return localClientTracker; 623 } 624 625 public OzoneInterface getDatabase() { 626 return database; 627 } 628 } 629 630 631 | Popular Tags |