1 23 package com.sun.enterprise.server.ss; 24 25 import java.io.IOException ; 26 import java.net.InetAddress ; 27 import java.net.InetSocketAddress ; 28 import java.net.ServerSocket ; 29 import java.net.Socket ; 30 import java.nio.channels.SelectionKey ; 31 import java.nio.channels.Selector ; 32 import java.nio.channels.ServerSocketChannel ; 33 import java.nio.channels.SocketChannel ; 34 import java.nio.channels.spi.SelectorProvider ; 35 import java.util.HashMap ; 36 import java.util.Iterator ; 37 import java.util.logging.Level ; 38 import java.util.logging.Logger ; 39 import com.sun.enterprise.server.PEMain; 40 import com.sun.enterprise.server.ondemand.entry.EntryPoint; 41 import com.sun.enterprise.server.ondemand.entry.ServerEntryHelper; 42 import com.sun.enterprise.server.ss.provider.ASSelectorProvider; 43 import com.sun.enterprise.server.ss.provider.ASServerSocket; 44 import com.sun.enterprise.server.ss.provider.PortConflictException; 45 import com.sun.enterprise.util.i18n.StringManager; 46 import com.sun.logging.LogDomains; 47 48 53 public class ASSocketService implements EntryPoint { 54 55 private static Logger logger = LogDomains.getLogger(LogDomains.CORE_LOGGER); 56 private static StringManager localStrings = 57 StringManager.getManager( ASSocketService.class); 58 59 private static HashMap <Integer , ASSocketService> managedPortsTable = 60 new HashMap <Integer , ASSocketService>(); 61 private static PEMain peMain = null; 62 private static InetAddress localHost = null; 63 64 private static final String SO_REUSEADDR_PROPERTY = 65 "com.sun.enterprise.server.ss.setReuseAddress"; 66 private static boolean setReuseAddress = 67 new Boolean (System.getProperty(SO_REUSEADDR_PROPERTY)); 68 69 private ServerSocket ss; 70 private ServerSocketChannel sschan; 71 private Selector sel; 72 73 private static final int TIMEOUT = 30 * 1000; private static boolean triggered = false; 75 76 static final int NOTSTARTED = 0; 77 static final int SERVICENOTIFIED = 1; 78 static final int STARTING = 2; 79 static final int STARTED = 3; 80 private int state = NOTSTARTED; 81 82 private static Object lock = new Object (); 83 private Object acceptLock = new Object (); 84 private ASSocketServiceConfig config = null; 85 86 ASSocketService(ASSocketServiceConfig config) { 87 this.config = config; 88 if ( localHost == null ) { 89 try { 90 localHost = InetAddress.getLocalHost(); 91 } catch ( Exception ex ) {} 92 } 93 } 94 95 void start() throws PortConflictException { 96 try { 97 config.init(); 98 _initializeService(); 99 Selector select = createListeningSelector(); 100 (new EntryPointThread(select)).start(); 101 102 if ( logger.isLoggable(Level.FINE) ) { 103 logger.fine("ASSocketService Successfully started for " + config); 104 } 105 } catch(IOException ie){ 106 String i18nMsg = localStrings.getString( 107 "socketservice.port_conflict", new Object []{String.valueOf(config.getPort())}); 108 throw new PortConflictException(config.getPort(),i18nMsg, ie); 109 } 110 } 111 112 void _reInitializeService() throws IOException { 113 ASSelectorProvider provider = 114 (ASSelectorProvider) SelectorProvider.provider(); 115 provider.clear(config.getPort()); 116 synchronized (managedPortsTable) { 117 managedPortsTable.remove(config.getPort()); 119 } 120 121 try { 122 if (this.sel != null) { 123 this.sel.close(); 124 } 125 } catch (Exception e) { 126 logger.log(Level.FINEST, e.getMessage(), e); 127 } 128 129 int oldPort = config.getPort(); 130 config.init(); 131 141 } 142 143 void _initializeService() throws IOException { 144 synchronized (managedPortsTable) { 145 managedPortsTable.put(config.getPort(), this); 147 } 148 sschan = ServerSocketChannel.open(); 150 ss = sschan.socket(); 151 if (setReuseAddress) { 152 ss.setReuseAddress(true); 153 } 154 ss.bind(config.getSocketAddress()); 155 } 156 157 static boolean close(int port, ServerSocket sock, ServerSocketChannel channel) 158 throws IOException { 159 160 ASSocketService savedSS = null; 161 if (port > 0) { 162 savedSS = ASSocketService.get(port); 163 if (savedSS != null) { if (savedSS.entryBeingProcessed()) { 165 ASSelectorProvider pr = (ASSelectorProvider) 167 SelectorProvider.provider(); 168 pr.setPortState(port, ASSelectorProvider.PORT_BOUND); 169 return false; 170 } 171 } 172 } 173 174 boolean closed = false; 175 try { 176 if (channel != null) { 177 if (channel.isOpen()) { 178 closed = true; 179 channel.close(); 180 } 181 } 182 if (sock != null) { 183 if (sock.isClosed() == false) { 184 closed = true; 185 sock.close(); 186 } 187 } 188 } finally { 189 if (savedSS != null && closed) { 190 ASSocketService.reInitializeService(port); 191 } 192 } 193 194 return true; 195 196 } 197 198 static void reInitializeService(int port) throws IOException { 199 ASSocketService savedSS = ASSocketService.get(port); 200 if (savedSS != null) { 201 savedSS._reInitializeService(); 202 } 203 } 204 205 Selector createListeningSelector() { 206 try { 207 sschan.configureBlocking(false); 208 this.sel = Selector.open(); 209 sschan.register(sel, SelectionKey.OP_ACCEPT); 210 } catch (Exception e) { 211 logger.log(Level.SEVERE, e.getMessage(), e); 212 } 213 return this.sel; 214 } 215 216 static void removeListeningSelector(int port) { 217 try { 218 ASSocketService savedSS = get(port); 219 savedSS.sel.close(); 220 savedSS.sschan.configureBlocking(true); 221 } catch (Exception e) { 222 logger.log(Level.SEVERE, e.getMessage(), e); 223 } 224 } 225 226 static ServerSocket getServerSocket(int port) { 227 ASSocketService a = managedPortsTable.get(port); 228 return a.ss; 229 } 230 231 232 static ServerSocketChannel getServerSocketChannel(int port) { 233 ASSocketService a = managedPortsTable.get(port); 234 return a.sschan; 235 } 236 237 static boolean exists(int port) { 238 return managedPortsTable.containsKey(port); 239 } 240 241 static ASSocketService get(int port) { 242 return managedPortsTable.get(port); 243 } 244 245 static void initialize() { 246 if ( peMain == null ) { 247 peMain = com.sun.enterprise.server.PEMain.getInstance(); 248 } 249 } 250 251 boolean entryBeingProcessed() { 252 return state != STARTED; 253 } 254 255 public static boolean socketServiceNotified(int port) { 256 ASSocketService ss = ASSocketService.get(port); 257 if (ss != null) { 258 return ss._socketServiceNotified(port); 259 } else { 260 return true; 261 } 262 } 263 264 boolean _socketServiceNotified(int port) { 265 if (state == NOTSTARTED) { 266 if (!ServerEntryHelper.isNotifiedByPortEntryContext(port)) { 268 state = SERVICENOTIFIED; 269 return false; 270 } 271 } 272 return true; 273 } 274 275 public void generateEntryContext(Object context) { 276 if ( logger.isLoggable(Level.FINE) ) { 277 logger.fine("In ASSocketService.generateEntryContext for context " + context); 278 } 279 ServerEntryHelper.generatePortEntryContext((Integer ) context); 280 } 281 282 static void waitOnAccept(SocketChannel sc) { 283 if ( peMain.isStartingUp() ) { 286 waitOnAccept(sc.socket()); 287 } else { 288 waitForServiceStartUp(sc.socket()); 289 } 290 291 } 292 293 static void waitOnAccept(Socket s) { 298 if ( peMain.isStartingUp() ) { 299 int localPort = s.getLocalPort(); 300 if ( !exists(localPort) ) { return; 302 } 303 304 Integer remotePort = new Integer (s.getPort()); 306 synchronized ( peMain ) { 307 while ( peMain.isStartingUp() && ! hasClientSocketLocalPorts(s) ) { 308 if ( logger.isLoggable(Level.FINE) ) { 309 logger.fine("In ASSocketService.waitOnAccept for localport " + localPort); 310 } 311 try { 312 peMain.wait(); 313 } catch ( Exception ex ) {} 314 } 315 } 316 } 317 318 waitForServiceStartUp(s); 319 } 320 321 static void waitForServiceStartUp(Socket s) { 322 ASSocketService savedService = get(s.getLocalPort()); 323 if ( savedService != null ) { 324 savedService._waitForServiceStartUp(s); 325 } 326 } 327 328 void _waitForServiceStartUp(Socket s) { 333 if ( entryBeingProcessed() ) { 334 int localPort = s.getLocalPort(); 335 336 Integer remotePort = new Integer (s.getPort()); 338 synchronized ( acceptLock ) { 339 while ( entryBeingProcessed() && 340 ! ASSocketService.hasClientSocketLocalPorts(s) ) { 341 if ( logger.isLoggable(Level.FINE) ) { 342 logger.fine("In ASSocketService.waitForServiceStartUp for localport " + localPort); 343 } 344 try { 345 acceptLock.wait(); 346 } catch ( Exception ex ) {} 347 } 348 } 349 } 350 351 } 352 353 static void clientSocketConnected(Socket s) { 354 boolean toAdd = true; 355 if ( peMain.isStartingUp() ) { 356 if ( logger.isLoggable(Level.FINE) ) { 357 logger.fine("In ASSocketService.clientSocketConnected, adding port " 358 + s.getLocalPort()); 359 } 360 361 synchronized ( peMain ) { 362 putClientSocketLocalPort(s); 363 toAdd = false; 364 peMain.notifyAll(); 365 } 366 } 367 368 ASSocketService service = ASSocketService.get(s.getPort()); 369 if (service != null && service.entryBeingProcessed()) { 370 synchronized ( service.acceptLock ) { 371 if (toAdd) { 372 putClientSocketLocalPort(s); 373 } 374 service.acceptLock.notifyAll(); 375 } 376 } 377 378 } 379 380 static void putClientSocketLocalPort(Socket s) { 381 int serverPort = s.getPort(); 382 if (exists(serverPort)) { 383 ASServerSocket ss = (ASServerSocket) getServerSocket(serverPort); 384 ss.addClientSocketLocalPort(s.getLocalPort()); 385 } 386 } 387 388 static boolean hasClientSocketLocalPorts(Socket s) { 389 ASServerSocket ss = (ASServerSocket) getServerSocket(s.getLocalPort()); 390 return ss.hasClientSocketLocalPorts(); 391 } 392 393 static boolean isLocalClient(Socket s) { 394 InetAddress remoteAddr = s.getInetAddress(); 396 return ( remoteAddr.equals(localHost) 397 || remoteAddr.isSiteLocalAddress() 398 || remoteAddr.isLinkLocalAddress() 399 || remoteAddr.isLoopbackAddress() 400 || remoteAddr.isAnyLocalAddress()); 401 } 402 403 static boolean isServerStartingUp() { 404 return peMain.isStartingUp(); 405 } 406 407 static boolean isServerStartingUp(int port) { 408 if (isServerStartingUp() == true) { 409 return true; 410 } 411 if (port > 0 ) { 412 ASSocketService savedSS = ASSocketService.get(port); 413 if (savedSS != null) { 414 return savedSS.entryBeingProcessed(); 415 } 416 } 417 return false; 418 } 419 420 public static void triggerServerExit(){ 421 synchronized (lock) { 422 triggered = true; 423 lock.notifyAll(); 424 } 425 } 426 427 public static void waitForClientNotification(){ 428 synchronized (lock) { 429 if (triggered == false) { 430 try { 431 lock.wait(TIMEOUT); 432 } catch (Exception e ) { 433 e.printStackTrace(); 434 } 435 } 436 } 437 } 438 439 450 public static void waitOnClientConnection(Socket s) { 451 int port = s.getPort(); 452 ASSocketService ss = ASSocketService.get(port); 453 if (ss != null) { 454 ss._waitOnClientConnection(); 455 } 456 } 457 458 void _waitOnClientConnection() { 459 if (entryBeingProcessed()) { 460 synchronized (acceptLock) { 461 try { 462 while (entryBeingProcessed()) { 463 acceptLock.wait(); 464 } 465 } catch (InterruptedException ie) { 466 } 467 } 468 } 469 } 470 471 class EntryPointThread extends Thread { 472 473 private Selector selector = null; 474 475 EntryPointThread(Selector selector) { 476 this.selector = selector; 477 } 478 479 public void run() { 480 481 selectorblock: 482 while (true) { 483 try { 484 selector.select(); 485 Iterator it = selector.selectedKeys().iterator(); 486 while (it.hasNext()) { 487 SelectionKey selKey = (SelectionKey )it.next(); 488 if (selKey.isValid() && selKey.isAcceptable()) { 489 it.remove(); 490 if (state != SERVICENOTIFIED) { 496 if (peMain.isStartingUp()) { 497 synchronized (peMain) { 498 try { 499 while (peMain.isStartingUp()) { 500 peMain.wait(); 501 } 502 } catch (Exception e) {} 503 } 504 } 505 } 506 break selectorblock; 507 } 508 } 509 510 } catch (Exception e) { 511 if (logger.isLoggable(Level.FINEST)) { 512 logger.log(Level.FINEST, e.getMessage(), e); 513 } 514 break; 515 } 520 } 521 522 523 try { 524 state = STARTING; 525 generateEntryContext(new Integer (config.getPort())); 526 state = STARTED; 527 synchronized (acceptLock) { 528 acceptLock.notifyAll(); 529 } 530 } catch (Exception e) { 531 logger.log(Level.SEVERE, e.getMessage(), e); 532 } 533 } 534 } 535 536 } 537 | Popular Tags |