1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.corba.se.impl.activation; 27 28 /** 29 * 30 * @author Rohit Garg 31 * @author Ken Cavanaugh 32 * @author Hemanth Puttaswamy 33 * @since JDK1.2 34 */ 35 36 import java.lang.reflect.Constructor; 37 import java.util.ArrayList; 38 import java.util.HashMap; 39 import java.util.Iterator; 40 import java.util.NoSuchElementException; 41 42 import org.omg.CORBA.OBJECT_NOT_EXIST; 43 import org.omg.CORBA.SystemException; 44 45 import com.sun.corba.se.spi.activation.EndPointInfo; 46 import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT; 47 import com.sun.corba.se.spi.activation.ORBPortInfo; 48 import com.sun.corba.se.spi.activation.Repository; 49 import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocation; 50 import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB; 51 import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef; 52 import com.sun.corba.se.spi.activation._ServerManagerImplBase; 53 import com.sun.corba.se.spi.activation.ServerAlreadyActive; 54 import com.sun.corba.se.spi.activation.ServerAlreadyInstalled; 55 import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled; 56 import com.sun.corba.se.spi.activation.ServerNotRegistered; 57 import com.sun.corba.se.spi.activation.ORBAlreadyRegistered; 58 import com.sun.corba.se.spi.activation.ServerHeldDown; 59 import com.sun.corba.se.spi.activation.ServerNotActive; 60 import com.sun.corba.se.spi.activation.NoSuchEndPoint; 61 import com.sun.corba.se.spi.activation.InvalidORBid; 62 import com.sun.corba.se.spi.activation.Server; 63 import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT; 64 import com.sun.corba.se.spi.ior.IORTemplate ; 65 import com.sun.corba.se.spi.ior.IOR ; 66 import com.sun.corba.se.spi.ior.ObjectKey ; 67 import com.sun.corba.se.spi.ior.ObjectKeyTemplate ; 68 import com.sun.corba.se.spi.ior.IORFactories ; 69 import com.sun.corba.se.spi.ior.iiop.GIOPVersion ; 70 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ; 71 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ; 72 import com.sun.corba.se.spi.ior.iiop.IIOPFactories ; 73 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo; 74 import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor; 75 import com.sun.corba.se.spi.orb.ORB ; 76 import com.sun.corba.se.spi.protocol.ForwardException; 77 import com.sun.corba.se.spi.transport.CorbaTransportManager; 78 79 import com.sun.corba.se.spi.logging.CORBALogDomains ; 80 import com.sun.corba.se.impl.logging.ActivationSystemException ; 81 82 import com.sun.corba.se.impl.oa.poa.BadServerIdHandler; 83 import com.sun.corba.se.impl.orbutil.ORBConstants; 84 import com.sun.corba.se.impl.orbutil.ORBUtility; 85 import com.sun.corba.se.impl.util.Utility; 86 87 public class ServerManagerImpl extends _ServerManagerImplBase 88 implements BadServerIdHandler 89 { 90 // Using HashMap, since synchronization should be done by the calling 91 // routines 92 HashMap serverTable; 93 Repository repository; 94 95 CorbaTransportManager transportManager; 96 int initialPort; 97 ORB orb; 98 ActivationSystemException wrapper; 99 String dbDirName; 100 boolean debug = false ; 101 102 private int serverStartupDelay; 103 104 ServerManagerImpl(ORB orb, CorbaTransportManager transportManager, 105 Repository repository, String dbDirName, boolean debug) 106 { 107 this.orb = orb; 108 wrapper = ActivationSystemException.get( orb, CORBALogDomains.ORBD_ACTIVATOR ) ; 109 110 this.transportManager = transportManager; // REVISIT - NOT USED. 111 this.repository = repository; 112 this.dbDirName = dbDirName; 113 this.debug = debug ; 114 115 LegacyServerSocketEndPointInfo endpoint = 116 orb.getLegacyServerSocketManager() 117 .legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING); 118 119 initialPort = ((SocketOrChannelAcceptor)endpoint) 120 .getServerSocket().getLocalPort(); 121 serverTable = new HashMap(256); 122 123 // The ServerStartupDelay is the delay added after the Server registers 124 // end point information. This is to allow the server to completely 125 // initialize after ORB is instantiated. 126 serverStartupDelay = ORBConstants.DEFAULT_SERVER_STARTUP_DELAY; 127 String delay = System.getProperty( ORBConstants.SERVER_STARTUP_DELAY); 128 if( delay != null ) { 129 try { 130 serverStartupDelay = Integer.parseInt( delay ); 131 } catch ( Exception e ) { 132 // Just use the default 1000 milliseconds as the default 133 } 134 } 135 136 Class cls = orb.getORBData( ).getBadServerIdHandler(); 137 if( cls == null ) { 138 orb.setBadServerIdHandler( this ); 139 } else { 140 orb.initBadServerIdHandler() ; 141 } 142 143 orb.connect(this); 144 ProcessMonitorThread.start( serverTable ); 145 } 146 147 public void activate(int serverId) 148 throws ServerAlreadyActive, ServerNotRegistered, ServerHeldDown 149 { 150 151 ServerLocation location; 152 ServerTableEntry entry; 153 Integer key = new Integer(serverId); 154 155 synchronized(serverTable) { 156 entry = (ServerTableEntry) serverTable.get(key); 157 } 158 159 if (entry != null && entry.isActive()) { 160 if (debug) 161 System.out.println( "ServerManagerImpl: activate for server Id " + 162 serverId + " failed because server is already active. " + 163 "entry = " + entry ) ; 164 165 throw new ServerAlreadyActive( serverId ); 166 } 167 168 // locate the server 169 try { 170 171 // We call getEntry here so that state of the entry is 172 // checked for validity before we actually go and locate a server 173 174 entry = getEntry(serverId); 175 176 if (debug) 177 System.out.println( "ServerManagerImpl: locateServer called with " + 178 " serverId=" + serverId + " endpointType=" 179 + IIOP_CLEAR_TEXT.value + " block=false" ) ; 180 181 location = locateServer(entry, IIOP_CLEAR_TEXT.value, false); 182 183 if (debug) 184 System.out.println( "ServerManagerImpl: activate for server Id " + 185 serverId + " found location " + 186 location.hostname + " and activated it" ) ; 187 } catch (NoSuchEndPoint ex) { 188 if (debug) 189 System.out.println( "ServerManagerImpl: activate for server Id " + 190 " threw NoSuchEndpoint exception, which was ignored" ); 191 } 192 } 193 194 public void active(int serverId, Server server) throws ServerNotRegistered 195 { 196 ServerTableEntry entry; 197 Integer key = new Integer(serverId); 198 199 synchronized (serverTable) { 200 entry = (ServerTableEntry) serverTable.get(key); 201 202 if (entry == null) { 203 if (debug) 204 System.out.println( "ServerManagerImpl: active for server Id " + 205 serverId + " called, but no such server is registered." ) ; 206 207 throw wrapper.serverNotExpectedToRegister() ; 208 } else { 209 if (debug) 210 System.out.println( "ServerManagerImpl: active for server Id " + 211 serverId + " called. This server is now active." ) ; 212 213 entry.register(server); 214 } 215 } 216 } 217 218 public void registerEndpoints( int serverId, String orbId, 219 EndPointInfo [] endpointList ) throws NoSuchEndPoint, ServerNotRegistered, 220 ORBAlreadyRegistered 221 { 222 // orbId is ignored for now 223 ServerTableEntry entry; 224 Integer key = new Integer(serverId); 225 226 synchronized (serverTable) { 227 entry = (ServerTableEntry) serverTable.get(key); 228 229 if (entry == null) { 230 if (debug) 231 System.out.println( 232 "ServerManagerImpl: registerEndpoint for server Id " + 233 serverId + " called, but no such server is registered." ) ; 234 235 throw wrapper.serverNotExpectedToRegister() ; 236 } else { 237 if (debug) 238 System.out.println( 239 "ServerManagerImpl: registerEndpoints for server Id " + 240 serverId + " called. This server is now active." ) ; 241 242 entry.registerPorts( orbId, endpointList ); 243 244 } 245 } 246 } 247 248 public int[] getActiveServers() 249 { 250 ServerTableEntry entry; 251 int[] list = null; 252 253 synchronized (serverTable) { 254 // unlike vectors, list is not synchronized 255 256 ArrayList servers = new ArrayList(0); 257 258 Iterator serverList = serverTable.keySet().iterator(); 259 260 try { 261 while (serverList.hasNext()) { 262 Integer key = (Integer) serverList.next(); 263 // get an entry 264 entry = (ServerTableEntry) serverTable.get(key); 265 266 if (entry.isValid() && entry.isActive()) { 267 servers.add(entry); 268 } 269 } 270 } catch (NoSuchElementException e) { 271 // all done 272 } 273 274 // collect the active entries 275 list = new int[servers.size()]; 276 for (int i = 0; i < servers.size(); i++) { 277 entry = (ServerTableEntry) servers.get(i); 278 list[i] = entry.getServerId(); 279 } 280 } 281 282 if (debug) { 283 StringBuffer sb = new StringBuffer() ; 284 for (int ctr=0; ctr<list.length; ctr++) { 285 sb.append( ' ' ) ; 286 sb.append( list[ctr] ) ; 287 } 288 289 System.out.println( "ServerManagerImpl: getActiveServers returns" + 290 sb.toString() ) ; 291 } 292 293 return list; 294 } 295 296 public void shutdown(int serverId) throws ServerNotActive 297 { 298 ServerTableEntry entry; 299 Integer key = new Integer(serverId); 300 301 synchronized(serverTable) { 302 entry = (ServerTableEntry) serverTable.remove(key); 303 304 if (entry == null) { 305 if (debug) 306 System.out.println( "ServerManagerImpl: shutdown for server Id " + 307 serverId + " throws ServerNotActive." ) ; 308 309 throw new ServerNotActive( serverId ); 310 } 311 312 try { 313 entry.destroy(); 314 315 if (debug) 316 System.out.println( "ServerManagerImpl: shutdown for server Id " + 317 serverId + " completed." ) ; 318 } catch (Exception e) { 319 if (debug) 320 System.out.println( "ServerManagerImpl: shutdown for server Id " + 321 serverId + " threw exception " + e ) ; 322 } 323 } 324 } 325 326 private ServerTableEntry getEntry( int serverId ) 327 throws ServerNotRegistered 328 { 329 Integer key = new Integer(serverId); 330 ServerTableEntry entry = null ; 331 332 synchronized (serverTable) { 333 entry = (ServerTableEntry) serverTable.get(key); 334 335 if (debug) 336 if (entry == null) { 337 System.out.println( "ServerManagerImpl: getEntry: " + 338 "no active server found." ) ; 339 } else { 340 System.out.println( "ServerManagerImpl: getEntry: " + 341 " active server found " + entry + "." ) ; 342 } 343 344 if ((entry != null) && (!entry.isValid())) { 345 serverTable.remove(key); 346 entry = null; 347 } 348 349 if (entry == null) { 350 ServerDef serverDef = repository.getServer(serverId); 351 352 entry = new ServerTableEntry( wrapper, 353 serverId, serverDef, initialPort, dbDirName, false, debug); 354 serverTable.put(key, entry); 355 entry.activate() ; 356 } 357 } 358 359 return entry ; 360 } 361 362 private ServerLocation locateServer (ServerTableEntry entry, String endpointType, 363 boolean block) 364 throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown 365 { 366 ServerLocation location = new ServerLocation() ; 367 368 // if server location is desired, then wait for the server 369 // to register back, then return location 370 371 ORBPortInfo [] serverORBAndPortList; 372 if (block) { 373 try { 374 serverORBAndPortList = entry.lookup(endpointType); 375 } catch (Exception ex) { 376 if (debug) 377 System.out.println( "ServerManagerImpl: locateServer: " + 378 "server held down" ) ; 379 380 throw new ServerHeldDown( entry.getServerId() ); 381 } 382 383 String host = 384 orb.getLegacyServerSocketManager() 385 .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName(); 386 location.hostname = host ; 387 int listLength; 388 if (serverORBAndPortList != null) { 389 listLength = serverORBAndPortList.length; 390 } else { 391 listLength = 0; 392 } 393 location.ports = new ORBPortInfo[listLength]; 394 for (int i = 0; i < listLength; i++) { 395 location.ports[i] = new ORBPortInfo(serverORBAndPortList[i].orbId, 396 serverORBAndPortList[i].port) ; 397 398 if (debug) 399 System.out.println( "ServerManagerImpl: locateServer: " + 400 "server located at location " + 401 location.hostname + " ORBid " + 402 serverORBAndPortList[i].orbId + 403 " Port " + serverORBAndPortList[i].port) ; 404 } 405 } 406 407 return location; 408 } 409 410 private ServerLocationPerORB locateServerForORB (ServerTableEntry entry, String orbId, 411 boolean block) 412 throws InvalidORBid, ServerNotRegistered, ServerHeldDown 413 { 414 ServerLocationPerORB location = new ServerLocationPerORB() ; 415 416 // if server location is desired, then wait for the server 417 // to register back, then return location 418 419 EndPointInfo [] endpointInfoList; 420 if (block) { 421 try { 422 endpointInfoList = entry.lookupForORB(orbId); 423 } catch (InvalidORBid ex) { 424 throw ex; 425 } catch (Exception ex) { 426 if (debug) 427 System.out.println( "ServerManagerImpl: locateServerForORB: " + 428 "server held down" ) ; 429 430 throw new ServerHeldDown( entry.getServerId() ); 431 } 432 433 String host = 434 orb.getLegacyServerSocketManager() 435 .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName(); 436 location.hostname = host ; 437 int listLength; 438 if (endpointInfoList != null) { 439 listLength = endpointInfoList.length; 440 } else { 441 listLength = 0; 442 } 443 location.ports = new EndPointInfo[listLength]; 444 for (int i = 0; i < listLength; i++) { 445 location.ports[i] = new EndPointInfo(endpointInfoList[i].endpointType, 446 endpointInfoList[i].port) ; 447 448 if (debug) 449 System.out.println( "ServerManagerImpl: locateServer: " + 450 "server located at location " + 451 location.hostname + " endpointType " + 452 endpointInfoList[i].endpointType + 453 " Port " + endpointInfoList[i].port) ; 454 } 455 } 456 457 return location; 458 } 459 460 public String[] getORBNames(int serverId) 461 throws ServerNotRegistered 462 { 463 try { 464 ServerTableEntry entry = getEntry( serverId ) ; 465 return (entry.getORBList()); 466 } catch (Exception ex) { 467 throw new ServerNotRegistered(serverId); 468 } 469 } 470 471 private ServerTableEntry getRunningEntry( int serverId ) 472 throws ServerNotRegistered 473 { 474 ServerTableEntry entry = getEntry( serverId ) ; 475 476 try { 477 // this is to see if the server has any listeners 478 ORBPortInfo [] serverORBAndPortList = entry.lookup(IIOP_CLEAR_TEXT.value) ; 479 } catch (Exception exc) { 480 return null ; 481 } 482 return entry; 483 484 } 485 486 public void install( int serverId ) 487 throws ServerNotRegistered, ServerHeldDown, ServerAlreadyInstalled 488 { 489 ServerTableEntry entry = getRunningEntry( serverId ) ; 490 if (entry != null) { 491 repository.install( serverId ) ; 492 entry.install() ; 493 } 494 } 495 496 public void uninstall( int serverId ) 497 throws ServerNotRegistered, ServerHeldDown, ServerAlreadyUninstalled 498 { 499 ServerTableEntry entry = 500 (ServerTableEntry) serverTable.get( new Integer(serverId) ); 501 502 if (entry != null) { 503 504 entry = 505 (ServerTableEntry) serverTable.remove(new Integer(serverId)); 506 507 if (entry == null) { 508 if (debug) 509 System.out.println( "ServerManagerImpl: shutdown for server Id " + 510 serverId + " throws ServerNotActive." ) ; 511 512 throw new ServerHeldDown( serverId ); 513 } 514 515 entry.uninstall(); 516 } 517 } 518 519 public ServerLocation locateServer (int serverId, String endpointType) 520 throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown 521 { 522 ServerTableEntry entry = getEntry( serverId ) ; 523 if (debug) 524 System.out.println( "ServerManagerImpl: locateServer called with " + 525 " serverId=" + serverId + " endpointType=" + 526 endpointType + " block=true" ) ; 527 528 // passing in entry to eliminate multiple lookups for 529 // the same entry in some cases 530 531 return locateServer(entry, endpointType, true); 532 } 533 534 /** This method is used to obtain the registered ports for an ORB. 535 * This is useful for custom Bad server ID handlers in ORBD. 536 */ 537 public ServerLocationPerORB locateServerForORB (int serverId, String orbId) 538 throws InvalidORBid, ServerNotRegistered, ServerHeldDown 539 { 540 ServerTableEntry entry = getEntry( serverId ) ; 541 542 // passing in entry to eliminate multiple lookups for 543 // the same entry in some cases 544 545 if (debug) 546 System.out.println( "ServerManagerImpl: locateServerForORB called with " + 547 " serverId=" + serverId + " orbId=" + orbId + 548 " block=true" ) ; 549 return locateServerForORB(entry, orbId, true); 550 } 551 552 553 public void handle(ObjectKey okey) 554 { 555 IOR newIOR = null; 556 ServerLocationPerORB location; 557 558 // we need to get the serverid and the orbid from the object key 559 ObjectKeyTemplate oktemp = okey.getTemplate(); 560 int serverId = oktemp.getServerId() ; 561 String orbId = oktemp.getORBId() ; 562 563 try { 564 // get the ORBName corresponding to the orbMapid, that was 565 // first registered by the server 566 ServerTableEntry entry = getEntry( serverId ) ; 567 location = locateServerForORB(entry, orbId, true); 568 569 if (debug) 570 System.out.println( "ServerManagerImpl: handle called for server id" + 571 serverId + " orbid " + orbId) ; 572 573 // we received a list of ports corresponding to an ORB in a 574 // particular server, now retrieve the one corresponding 575 // to IIOP_CLEAR_TEXT, and for other created the tagged 576 // components to be added to the IOR 577 578 int clearPort = 0; 579 EndPointInfo[] listenerPorts = location.ports; 580 for (int i = 0; i < listenerPorts.length; i++) { 581 if ((listenerPorts[i].endpointType).equals(IIOP_CLEAR_TEXT.value)) { 582 clearPort = listenerPorts[i].port; 583 break; 584 } 585 } 586 587 // create a new IOR with the correct port and correct tagged 588 // components 589 IIOPAddress addr = IIOPFactories.makeIIOPAddress( orb, 590 location.hostname, clearPort ) ; 591 IIOPProfileTemplate iptemp = 592 IIOPFactories.makeIIOPProfileTemplate( 593 orb, GIOPVersion.V1_2, addr ) ; 594 if (GIOPVersion.V1_2.supportsIORIIOPProfileComponents()) { 595 iptemp.add(IIOPFactories.makeCodeSetsComponent(orb)); 596 iptemp.add(IIOPFactories.makeMaxStreamFormatVersionComponent()); 597 } 598 IORTemplate iortemp = IORFactories.makeIORTemplate(oktemp) ; 599 iortemp.add( iptemp ) ; 600 601 newIOR = iortemp.makeIOR(orb, "IDL:org/omg/CORBA/Object:1.0", 602 okey.getId() ); 603 } catch (Exception e) { 604 throw wrapper.errorInBadServerIdHandler( e ) ; 605 } 606 607 if (debug) 608 System.out.println( "ServerManagerImpl: handle " + 609 "throws ForwardException" ) ; 610 611 612 try { 613 // This delay is required in case of Server is activated or 614 // re-activated the first time. Server needs some time before 615 // handling all the requests. 616 // (Talk to Ken to see whether there is a better way of doing this). 617 Thread.sleep( serverStartupDelay ); 618 } catch ( Exception e ) { 619 System.out.println( "Exception = " + e ); 620 e.printStackTrace(); 621 } 622 623 throw new ForwardException(orb, newIOR); 624 } 625 626 public int getEndpoint(String endpointType) throws NoSuchEndPoint 627 { 628 return orb.getLegacyServerSocketManager() 629 .legacyGetTransientServerPort(endpointType); 630 } 631 632 public int getServerPortForType(ServerLocationPerORB location, 633 String endPointType) 634 throws NoSuchEndPoint 635 { 636 EndPointInfo[] listenerPorts = location.ports; 637 for (int i = 0; i < listenerPorts.length; i++) { 638 if ((listenerPorts[i].endpointType).equals(endPointType)) { 639 return listenerPorts[i].port; 640 } 641 } 642 throw new NoSuchEndPoint(); 643 } 644 645 }