Mon, 08 Apr 2013 23:12:03 +0100
8001032: Restrict object access
Summary: Restrict object access; fix reviewed also by Alexander Fomin
Reviewed-by: alanb, ahgross
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 */
26 package com.sun.corba.se.impl.activation;
28 /**
29 *
30 * @author Rohit Garg
31 * @author Ken Cavanaugh
32 * @author Hemanth Puttaswamy
33 * @since JDK1.2
34 */
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;
42 import org.omg.CORBA.OBJECT_NOT_EXIST;
43 import org.omg.CORBA.SystemException;
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;
79 import com.sun.corba.se.spi.logging.CORBALogDomains ;
80 import com.sun.corba.se.impl.logging.ActivationSystemException ;
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;
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;
95 CorbaTransportManager transportManager;
96 int initialPort;
97 ORB orb;
98 ActivationSystemException wrapper;
99 String dbDirName;
100 boolean debug = false ;
102 private int serverStartupDelay;
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 ) ;
110 this.transportManager = transportManager; // REVISIT - NOT USED.
111 this.repository = repository;
112 this.dbDirName = dbDirName;
113 this.debug = debug ;
115 LegacyServerSocketEndPointInfo endpoint =
116 orb.getLegacyServerSocketManager()
117 .legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING);
119 initialPort = ((SocketOrChannelAcceptor)endpoint)
120 .getServerSocket().getLocalPort();
121 serverTable = new HashMap(256);
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 }
136 Class cls = orb.getORBData( ).getBadServerIdHandler();
137 if( cls == null ) {
138 orb.setBadServerIdHandler( this );
139 } else {
140 orb.initBadServerIdHandler() ;
141 }
143 orb.connect(this);
144 ProcessMonitorThread.start( serverTable );
145 }
147 public void activate(int serverId)
148 throws ServerAlreadyActive, ServerNotRegistered, ServerHeldDown
149 {
151 ServerLocation location;
152 ServerTableEntry entry;
153 Integer key = new Integer(serverId);
155 synchronized(serverTable) {
156 entry = (ServerTableEntry) serverTable.get(key);
157 }
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 ) ;
165 throw new ServerAlreadyActive( serverId );
166 }
168 // locate the server
169 try {
171 // We call getEntry here so that state of the entry is
172 // checked for validity before we actually go and locate a server
174 entry = getEntry(serverId);
176 if (debug)
177 System.out.println( "ServerManagerImpl: locateServer called with " +
178 " serverId=" + serverId + " endpointType="
179 + IIOP_CLEAR_TEXT.value + " block=false" ) ;
181 location = locateServer(entry, IIOP_CLEAR_TEXT.value, false);
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 }
194 public void active(int serverId, Server server) throws ServerNotRegistered
195 {
196 ServerTableEntry entry;
197 Integer key = new Integer(serverId);
199 synchronized (serverTable) {
200 entry = (ServerTableEntry) serverTable.get(key);
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." ) ;
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." ) ;
213 entry.register(server);
214 }
215 }
216 }
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);
226 synchronized (serverTable) {
227 entry = (ServerTableEntry) serverTable.get(key);
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." ) ;
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." ) ;
242 entry.registerPorts( orbId, endpointList );
244 }
245 }
246 }
248 public int[] getActiveServers()
249 {
250 ServerTableEntry entry;
251 int[] list = null;
253 synchronized (serverTable) {
254 // unlike vectors, list is not synchronized
256 ArrayList servers = new ArrayList(0);
258 Iterator serverList = serverTable.keySet().iterator();
260 try {
261 while (serverList.hasNext()) {
262 Integer key = (Integer) serverList.next();
263 // get an entry
264 entry = (ServerTableEntry) serverTable.get(key);
266 if (entry.isValid() && entry.isActive()) {
267 servers.add(entry);
268 }
269 }
270 } catch (NoSuchElementException e) {
271 // all done
272 }
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 }
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 }
289 System.out.println( "ServerManagerImpl: getActiveServers returns" +
290 sb.toString() ) ;
291 }
293 return list;
294 }
296 public void shutdown(int serverId) throws ServerNotActive
297 {
298 ServerTableEntry entry;
299 Integer key = new Integer(serverId);
301 synchronized(serverTable) {
302 entry = (ServerTableEntry) serverTable.remove(key);
304 if (entry == null) {
305 if (debug)
306 System.out.println( "ServerManagerImpl: shutdown for server Id " +
307 serverId + " throws ServerNotActive." ) ;
309 throw new ServerNotActive( serverId );
310 }
312 try {
313 entry.destroy();
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 }
326 private ServerTableEntry getEntry( int serverId )
327 throws ServerNotRegistered
328 {
329 Integer key = new Integer(serverId);
330 ServerTableEntry entry = null ;
332 synchronized (serverTable) {
333 entry = (ServerTableEntry) serverTable.get(key);
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 }
344 if ((entry != null) && (!entry.isValid())) {
345 serverTable.remove(key);
346 entry = null;
347 }
349 if (entry == null) {
350 ServerDef serverDef = repository.getServer(serverId);
352 entry = new ServerTableEntry( wrapper,
353 serverId, serverDef, initialPort, dbDirName, false, debug);
354 serverTable.put(key, entry);
355 entry.activate() ;
356 }
357 }
359 return entry ;
360 }
362 private ServerLocation locateServer (ServerTableEntry entry, String endpointType,
363 boolean block)
364 throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
365 {
366 ServerLocation location = new ServerLocation() ;
368 // if server location is desired, then wait for the server
369 // to register back, then return location
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" ) ;
380 throw new ServerHeldDown( entry.getServerId() );
381 }
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) ;
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 }
407 return location;
408 }
410 private ServerLocationPerORB locateServerForORB (ServerTableEntry entry, String orbId,
411 boolean block)
412 throws InvalidORBid, ServerNotRegistered, ServerHeldDown
413 {
414 ServerLocationPerORB location = new ServerLocationPerORB() ;
416 // if server location is desired, then wait for the server
417 // to register back, then return location
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" ) ;
430 throw new ServerHeldDown( entry.getServerId() );
431 }
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) ;
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 }
457 return location;
458 }
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 }
471 private ServerTableEntry getRunningEntry( int serverId )
472 throws ServerNotRegistered
473 {
474 ServerTableEntry entry = getEntry( serverId ) ;
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;
484 }
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 }
496 public void uninstall( int serverId )
497 throws ServerNotRegistered, ServerHeldDown, ServerAlreadyUninstalled
498 {
499 ServerTableEntry entry =
500 (ServerTableEntry) serverTable.get( new Integer(serverId) );
502 if (entry != null) {
504 entry =
505 (ServerTableEntry) serverTable.remove(new Integer(serverId));
507 if (entry == null) {
508 if (debug)
509 System.out.println( "ServerManagerImpl: shutdown for server Id " +
510 serverId + " throws ServerNotActive." ) ;
512 throw new ServerHeldDown( serverId );
513 }
515 entry.uninstall();
516 }
517 }
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" ) ;
528 // passing in entry to eliminate multiple lookups for
529 // the same entry in some cases
531 return locateServer(entry, endpointType, true);
532 }
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 ) ;
542 // passing in entry to eliminate multiple lookups for
543 // the same entry in some cases
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 }
553 public void handle(ObjectKey okey)
554 {
555 IOR newIOR = null;
556 ServerLocationPerORB location;
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() ;
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);
569 if (debug)
570 System.out.println( "ServerManagerImpl: handle called for server id" +
571 serverId + " orbid " + orbId) ;
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
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 }
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 ) ;
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 }
607 if (debug)
608 System.out.println( "ServerManagerImpl: handle " +
609 "throws ForwardException" ) ;
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 }
623 throw new ForwardException(orb, newIOR);
624 }
626 public int getEndpoint(String endpointType) throws NoSuchEndPoint
627 {
628 return orb.getLegacyServerSocketManager()
629 .legacyGetTransientServerPort(endpointType);
630 }
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 }
645 }