| 1 14 15 package org.quickserver.net.server; 16 17 import java.io.*; 18 import java.net.*; 19 20 import org.quickserver.net.*; 21 import org.quickserver.net.qsadmin.*; 23 import java.util.logging.*; 25 import org.quickserver.util.pool.*; 27 import org.quickserver.util.pool.thread.*; 28 import org.apache.commons.pool.*; 29 import org.quickserver.util.xmlreader.*; 30 import org.quickserver.sql.*; 31 import java.util.*; 33 import org.quickserver.util.*; 35 import java.util.regex.*; 36 import org.quickserver.security.*; 38 import javax.net.ssl.*; 40 import javax.net.*; 41 import java.security.*; 42 import java.security.cert.*; 43 import org.quickserver.util.io.*; 44 import java.nio.*; 46 import java.nio.channels.*; 47 import org.quickserver.net.server.impl.*; 48 49 113 public class QuickServer implements Runnable , Service, Cloneable , Serializable { 114 117 private final static String VER = "1.4.7"; private final static String NEW_LINE = "\r\n"; 121 122 static { 123 System.out.print("Loading QuickServer v"+getVersion()+" "); 124 } 125 126 private String serverBanner; 127 128 private String clientAuthenticationHandlerString; private String clientEventHandlerString; private String clientExtendedEventHandlerString; private String clientCommandHandlerString; 132 private String clientObjectHandlerString; private String clientBinaryHandlerString; private String clientWriteHandlerString; private String clientDataString; 136 137 private Authenticator authenticator; 138 private ClientAuthenticationHandler clientAuthenticationHandler; private ClientEventHandler clientEventHandler; private ClientExtendedEventHandler clientExtendedEventHandler; private ClientCommandHandler clientCommandHandler; 142 private ClientObjectHandler clientObjectHandler; private ClientBinaryHandler clientBinaryHandler; private ClientWriteHandler clientWriteHandler; private ClientData clientData; 146 protected Class clientDataClass; 147 148 private int serverPort = 9876; 149 private Thread t; private ServerSocket server; 151 private String serverName = "QuickServer"; 152 private long maxConnection = -1; 153 private int socketTimeout = 60 * 1000; private String maxConnectionMsg = "-ERR Server Busy. Max Connection Reached"; 155 private String timeoutMsg = "-ERR Timeout"; 156 private String maxAuthTryMsg = "-ERR Max Auth Try Reached"; 157 private int maxAuthTry = 5; 159 static { 160 System.out.print("."); 161 } 162 163 private InetAddress ipAddr; 165 private boolean stopServer; 166 private Object [] storeObjects; 167 private QSAdminServer adminServer; 168 169 private static final Logger logger = Logger.getLogger(QuickServer.class.getName()); 172 private Logger appLogger; 174 175 private long suspendMaxConnection; private String suspendMaxConnectionMsg; private int serviceState = Service.UNKNOWN; 179 180 static { 181 System.out.print("."); 182 } 183 184 private QuickServerConfig config = new QuickServerConfig(); 186 private String consoleLoggingformatter; 187 private String consoleLoggingLevel = "INFO"; 188 private ClientPool pool; 189 private ObjectPool clientHandlerPool; 190 private ObjectPool clientDataPool; 191 private DBPoolUtil dBPoolUtil; 192 193 private String loggingLevel = "INFO"; 195 196 private boolean skipValidation = false; 198 private boolean communicationLogging = true; 199 200 private String securityManagerClass; 202 private AccessConstraintConfig accessConstraintConfig; 203 private ClassLoader classLoader; 204 private String applicationJarPath; 205 private ServerHooks serverHooks; 206 private ArrayList listOfServerHooks; 207 208 static { 209 System.out.print("."); 210 } 211 212 private Secure secure; 214 private BasicServerConfig basicConfig = config; 215 private SSLContext sslc; 216 private KeyManager km[] = null; 217 private TrustManager tm[] = null; 218 private boolean runningSecure = false; 219 private SecureStoreManager secureStoreManager = null; 220 221 private Exception exceptionInRun = null; 222 223 private ServerSocketChannel serverSocketChannel; 225 private Selector selector; 226 private boolean blockingMode = true; 227 private ObjectPool byteBufferPool; 228 private java.util.Date lastStartTime; 229 private ClientIdentifier clientIdentifier; 230 private GhostSocketReaper ghostSocketReaper; 231 private PoolManager poolManager; 232 private QSObjectPoolMaker qsObjectPoolMaker; 233 234 private DataMode defaultDataModeIN = DataMode.STRING; 236 private DataMode defaultDataModeOUT = DataMode.STRING; 237 238 private Throwable serviceError; 240 private Map registerChannelRequestMap; 241 242 static { 243 System.out.println(" Done"); 244 } 249 250 251 public static final String getVersion() { 252 return VER; 253 } 254 255 259 public static final float getVersionNo() { 260 return getVersionNo(VER); 261 } 262 263 267 public static final float getVersionNo(String ver) { 268 float version = 0; 270 int i = ver.indexOf(" "); if(i == -1) 272 i = ver.length(); 273 ver = ver.substring(0, i); 274 275 i = ver.indexOf("."); if(i!=-1) { 277 int j = ver.indexOf(".", i); 278 if(j!=-1) { 279 ver = ver.substring(0, i)+"."+ 280 MyString.replaceAll(ver.substring(i+1), ".", ""); 281 } 282 } 283 284 try { 285 version = Float.parseFloat(ver); 286 } catch(NumberFormatException e) { 287 throw new RuntimeException ("Corrupt QuickServer"); 288 } 289 return version; 290 } 291 292 296 public static String getNewLine() { 297 return NEW_LINE; 298 } 299 300 303 public String toString() { 304 return serverName + " : " + getPort(); 305 } 306 307 324 public QuickServer() { 325 } 326 327 338 public QuickServer(String commandHandler) { 339 setClientCommandHandler(commandHandler); 340 } 341 342 354 public QuickServer(String commandHandler,int port) { 355 this(commandHandler); setPort(port); 357 } 358 359 367 public void startServer() throws AppException { 368 logger.fine("Starting "+getName()); 369 370 if(isClosed() == false) { 371 logger.warning("Server "+getName()+" already running."); 372 throw new AppException("Server "+getName()+" already running."); 373 } 374 375 if(serverBanner == null) { 376 serverBanner = "\n-------------------------------" + 377 "\n Name : " + getName() + 378 "\n Port : " + getPort() + 379 "\n-------------------------------\n"; 380 logger.finest("Default Server Banner Generated"); 381 } 382 try { 383 loadApplicationClasses(); 384 385 Class clientIdentifierClass = 387 getClass(getBasicConfig().getAdvancedSettings().getClientIdentifier(), true); 388 clientIdentifier = (ClientIdentifier) 389 clientIdentifierClass.newInstance(); 390 clientIdentifier.setQuickServer(QuickServer.this); 391 392 Class poolManagerClass = 394 getClass(getBasicConfig().getObjectPoolConfig().getPoolManager(), true); 395 poolManager = (PoolManager) poolManagerClass.newInstance(); 396 397 Class qsObjectPoolMakerClass = getClass( 399 getBasicConfig().getAdvancedSettings().getQSObjectPoolMaker(), true); 400 qsObjectPoolMaker = (QSObjectPoolMaker) qsObjectPoolMakerClass.newInstance(); 401 402 loadServerHooksClasses(); 403 processServerHooks(ServerHook.PRE_STARTUP); 404 405 if(getSecure().isLoad()==true) 406 loadSSLContext(); 408 loadBusinessLogic(); 409 } catch(ClassNotFoundException e) { 410 logger.severe("Could not load class/s : " + e.getMessage()); 411 throw new AppException("Could not load class/s : " + e.getMessage()); 412 } catch(InstantiationException e) { 413 logger.severe("Could not instantiate class/s : " + e.getMessage()); 414 throw new AppException("Could not instantiate class/s : "+e.getMessage()); 415 } catch(IllegalAccessException e) { 416 logger.severe("Illegal access to class/s : " + e.getMessage()); 417 throw new AppException("Illegal access to class/s : " + e.getMessage()); 418 } catch(IOException e) { 419 logger.severe("IOException : " + e.getMessage()); 420 logger.fine("StackTrace:\n"+MyString.getStackTrace(e)); 421 throw new AppException("IOException : " + e.getMessage()); 422 } catch(Exception e) { 423 logger.severe("Exception : " + e.getMessage()); 424 logger.fine("StackTrace:\n"+MyString.getStackTrace(e)); 425 throw new AppException("Exception : " + e); 426 } 427 428 if(getSecurityManagerClass()!=null) { 430 System.setSecurityManager(getSecurityManager()); 431 } 432 433 blockingMode = getBasicConfig().getServerMode().getBlocking(); 434 435 setServiceState(Service.INIT); 436 t = new Thread (this, "QuickServer - "+getName()); 437 t.start(); 438 439 do { 440 Thread.yield(); 441 } while(getServiceState()==Service.INIT); 442 443 if(getServiceState()!=Service.RUNNING) { 444 if(exceptionInRun!=null) 445 throw new AppException("Could not start server "+getName() 446 +"! Details: "+exceptionInRun); 447 else 448 throw new AppException("Could not start server "+getName()); 449 } 450 lastStartTime = new java.util.Date (); 451 logger.fine("Started "+getName()+", Date: "+lastStartTime); 452 } 453 454 462 public void stopServer() throws AppException { 463 processServerHooks(ServerHook.PRE_SHUTDOWN); 464 logger.warning("Stopping "+getName()); 465 stopServer = true; 466 Socket death = null; 467 if(isClosed()==true) { 468 logger.warning("Server "+getName()+" is not running!"); 469 throw new AppException("Server "+getName()+" is not running!"); 470 } 471 try { 472 if(getBlockingMode()==true) { 473 if(getSecure().isEnable()==false) { 474 death = new Socket(server.getInetAddress(), 475 server.getLocalPort()); 476 death.getInputStream().read(); 477 death.close(); 478 } else { 479 death = getSSLSocketFactory().createSocket( 480 server.getInetAddress(), server.getLocalPort()); 481 Thread.currentThread().sleep(100); 482 death.close(); 483 } 484 } 485 486 if(serverSocketChannel!=null) { 487 serverSocketChannel.close(); 488 } 489 490 } catch(IOException e){ 491 logger.fine("IOError stopping "+getName()+": "+e); 492 } catch(Exception e){ 493 logger.warning("Error stopping "+getName()+": "+e); 494 throw new AppException("Error in stopServer "+getName()+": "+e); 495 } 496 497 for(int i=0;getServiceState()!=Service.STOPPED;i++) { 498 try { 499 Thread.sleep(60); 500 } catch(Exception e) { 501 logger.warning("Error waiting for "+getName()+" to fully stop. Error: "+e); 502 } 503 if(i>1000) { 504 logger.severe("Server was not stopped even after 10sec.. will terminate now."); 505 System.exit(-1); 506 } 507 } 508 if(adminServer==null || getQSAdminServer().getServer()!=this) { 509 setClassLoader(null); 511 } 512 logger.info("Stopped "+getName()); 513 } 514 515 522 public void restartServer() throws AppException { 523 stopServer(); 524 startServer(); 525 } 526 527 531 public String getName() { 532 return serverName; 533 } 534 539 public void setName(String name) { 540 serverName = name; 541 logger.finest("Set to : "+name); 542 } 543 544 548 public String getServerBanner() { 549 return serverBanner; 550 } 551 560 public void setServerBanner(String banner) { 561 serverBanner = banner; 562 logger.finest("Set to : "+banner); 563 } 564 565 571 public void setPort(int port) { 572 if(port<0) { 573 throw new IllegalArgumentException ("Port number can not be less than 0!"); 574 } 575 serverPort=port; 576 logger.finest("Set to "+port); 577 } 578 582 public int getPort() { 583 if(isClosed()==false) { 584 return server.getLocalPort(); 585 } 586 587 if(getSecure().isEnable()==false) { 588 return serverPort; 589 } else { 590 int _port = getSecure().getPort(); 591 if(_port == -1) 592 return serverPort; 593 else 594 return _port; 595 } 596 } 597 598 605 public void setClientCommandHandler(String handler) { 606 clientCommandHandlerString = handler; 607 logger.finest("Set to "+handler); 608 } 609 615 public String getClientCommandHandler() { 616 return clientCommandHandlerString; 617 } 618 619 627 public void setClientAuthenticationHandler(String authenticator) { 628 clientAuthenticationHandlerString = authenticator; 629 logger.finest("Set to "+authenticator); 630 } 631 637 public String getClientAuthenticationHandler() { 638 return clientAuthenticationHandlerString; 639 } 640 641 650 public void setAuthenticator(String authenticator) { 651 clientAuthenticationHandlerString = authenticator; 652 logger.finest("Set to "+authenticator); 653 } 654 661 public String getAuthenticator() { 662 return clientAuthenticationHandlerString; 663 } 664 665 671 public void setClientData(String data) { 672 this.clientDataString = data; 673 logger.finest("Set to "+data); 674 } 675 681 public String getClientData() { 682 return clientDataString; 683 } 684 685 690 public void setTimeout(int time) { 691 if(time>0) 692 socketTimeout = time; 693 else 694 socketTimeout = 0; 695 logger.finest("Set to "+socketTimeout); 696 } 697 701 public int getTimeout() { 702 return socketTimeout; 703 } 704 705 710 public void setMaxAuthTry(int authTry) { 711 maxAuthTry = authTry; 712 logger.finest("Set to "+authTry); 713 } 714 719 public int getMaxAuthTry() { 720 return maxAuthTry; 721 } 722 723 729 public void setMaxAuthTryMsg(String msg) { 730 maxAuthTryMsg = msg; 731 logger.finest("Set to "+msg); 732 } 733 738 public String getMaxAuthTryMsg() { 739 return maxAuthTryMsg; 740 } 741 742 747 public void setTimeoutMsg(String msg) { 748 timeoutMsg = msg; 749 logger.finest("Set to "+msg); 750 } 751 755 public String getTimeoutMsg() { 756 return timeoutMsg; 757 } 758 759 private TheClient initTheClient() { 760 TheClient theClient = new TheClient(); 761 theClient.setServer(QuickServer.this); 762 theClient.setTimeoutMsg(getTimeoutMsg()); 763 theClient.setMaxAuthTry(getMaxAuthTry()); theClient.setMaxAuthTryMsg(getMaxAuthTryMsg()); 765 766 theClient.setClientEventHandler(clientEventHandler); 767 theClient.setClientExtendedEventHandler(clientExtendedEventHandler); theClient.setClientCommandHandler(clientCommandHandler); 769 theClient.setClientObjectHandler(clientObjectHandler); theClient.setClientBinaryHandler(clientBinaryHandler); theClient.setClientWriteHandler(clientWriteHandler); theClient.setAuthenticator(authenticator); theClient.setClientAuthenticationHandler(clientAuthenticationHandler); theClient.setTimeout(socketTimeout); 775 theClient.setMaxConnectionMsg(maxConnectionMsg); 776 theClient.setCommunicationLogging(getCommunicationLogging()); return theClient; 778 } 779 780 public void run() { 781 exceptionInRun = null; 782 TheClient theClient = initTheClient(); 783 try { 784 stopServer = false; 785 786 closeAllPools(); 787 initAllPools(); 788 789 makeServerSocket(); 790 System.out.println(serverBanner); setServiceState(Service.RUNNING); 793 processServerHooks(ServerHook.POST_STARTUP); if(getBlockingMode()==false) { 795 runNonBlocking(theClient); 796 if(stopServer==true) { 797 logger.finest("Closing selector for "+getName()); 798 selector.close(); 799 } 800 return; 801 } else { 802 runBlocking(theClient); 803 } 804 } catch(BindException e) { 805 exceptionInRun = e; 806 logger.severe(getName()+" BindException for Port "+getPort()+" @ "+ 807 getBindAddr().getHostAddress()+" : "+e.getMessage()); 808 } catch(javax.net.ssl.SSLException e) { 809 exceptionInRun = e; 810 logger.severe("SSLException "+e); 811 logger.fine("StackTrace:\n"+MyString.getStackTrace(e)); 812 } catch(IOException e) { 813 exceptionInRun = e; 814 logger.severe("IOError "+e); 815 logger.fine("StackTrace:\n"+MyString.getStackTrace(e)); 816 } catch(Exception e) { 817 exceptionInRun = e; 818 logger.severe("Error "+e); 819 logger.fine("StackTrace:\n"+MyString.getStackTrace(e)); 820 } finally { 821 if(getBlockingMode()==true) { 822 logger.warning("Closing "+getName()); 823 try { 824 if(isClosed()==false) { 825 server.close(); 826 } 827 } catch(Exception e){ 828 throw new RuntimeException (e); 829 } 830 server = null; 831 serverSocketChannel = null; 832 833 setServiceState(Service.STOPPED); 834 logger.warning("Closed "+getName()); 835 836 processServerHooks(ServerHook.POST_SHUTDOWN); 837 } else if(getBlockingMode()==false && exceptionInRun!=null) { 838 logger.warning("Closing "+getName()+" - Had Error: "+exceptionInRun); 839 try { 840 if(isClosed()==false) { 841 if(serverSocketChannel!=null) 842 serverSocketChannel.close(); 843 if(server!=null) 844 server.close(); 845 } 846 } catch(Exception e){ 847 throw new RuntimeException (e); 848 } 849 850 server = null; 851 serverSocketChannel = null; 852 853 setServiceState(Service.STOPPED); 854 logger.warning("Closed "+getName()); 855 856 processServerHooks(ServerHook.POST_SHUTDOWN); 857 } 858 } 859 } 861 866 public void setMaxConnection(long maxConnection) { 867 if(getServiceState()==Service.SUSPENDED) 868 suspendMaxConnection = maxConnection; 869 else 870 this.maxConnection = maxConnection; 871 logger.finest("Set to "+maxConnection); 872 } 873 878 public long getMaxConnection() { 879 return maxConnection; 880 } 881 882 886 public long getClientCount() { 887 if(clientHandlerPool != null) { 888 try { 889 return getClientHandlerPool().getNumActive(); 890 } catch(Exception e) { 891 return 0; 892 } 893 } 894 return 0; 895 } 896 897 |