ServerManagerImpl.java revision 608:7e06bf1dcb09
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
26package 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
36import java.lang.reflect.Constructor;
37import java.util.ArrayList;
38import java.util.HashMap;
39import java.util.Iterator;
40import java.util.NoSuchElementException;
41
42import org.omg.CORBA.OBJECT_NOT_EXIST;
43import org.omg.CORBA.SystemException;
44
45import com.sun.corba.se.spi.activation.EndPointInfo;
46import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
47import com.sun.corba.se.spi.activation.ORBPortInfo;
48import com.sun.corba.se.spi.activation.Repository;
49import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocation;
50import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB;
51import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;
52import com.sun.corba.se.spi.activation._ServerManagerImplBase;
53import com.sun.corba.se.spi.activation.ServerAlreadyActive;
54import com.sun.corba.se.spi.activation.ServerAlreadyInstalled;
55import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled;
56import com.sun.corba.se.spi.activation.ServerNotRegistered;
57import com.sun.corba.se.spi.activation.ORBAlreadyRegistered;
58import com.sun.corba.se.spi.activation.ServerHeldDown;
59import com.sun.corba.se.spi.activation.ServerNotActive;
60import com.sun.corba.se.spi.activation.NoSuchEndPoint;
61import com.sun.corba.se.spi.activation.InvalidORBid;
62import com.sun.corba.se.spi.activation.Server;
63import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
64import com.sun.corba.se.spi.ior.IORTemplate ;
65import com.sun.corba.se.spi.ior.IOR ;
66import com.sun.corba.se.spi.ior.ObjectKey ;
67import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
68import com.sun.corba.se.spi.ior.IORFactories ;
69import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
70import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
71import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
72import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
73import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
74import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
75import com.sun.corba.se.spi.orb.ORB ;
76import com.sun.corba.se.spi.protocol.ForwardException;
77import com.sun.corba.se.spi.transport.CorbaTransportManager;
78
79import com.sun.corba.se.spi.logging.CORBALogDomains ;
80import com.sun.corba.se.impl.logging.ActivationSystemException ;
81
82import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
83import com.sun.corba.se.impl.orbutil.ORBConstants;
84import com.sun.corba.se.impl.orbutil.ORBUtility;
85import com.sun.corba.se.impl.util.Utility;
86
87public 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}
646