blob: 745f0aafadb0ad743820cf1a358eee6227fa5f20 [file] [log] [blame]
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.corba.se.impl.activation;
/**
*
* @author Rohit Garg
* @author Ken Cavanaugh
* @author Hemanth Puttaswamy
* @since JDK1.2
*/
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.omg.CORBA.OBJECT_NOT_EXIST;
import org.omg.CORBA.SystemException;
import com.sun.corba.se.spi.activation.EndPointInfo;
import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
import com.sun.corba.se.spi.activation.ORBPortInfo;
import com.sun.corba.se.spi.activation.Repository;
import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocation;
import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB;
import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;
import com.sun.corba.se.spi.activation._ServerManagerImplBase;
import com.sun.corba.se.spi.activation.ServerAlreadyActive;
import com.sun.corba.se.spi.activation.ServerAlreadyInstalled;
import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled;
import com.sun.corba.se.spi.activation.ServerNotRegistered;
import com.sun.corba.se.spi.activation.ORBAlreadyRegistered;
import com.sun.corba.se.spi.activation.ServerHeldDown;
import com.sun.corba.se.spi.activation.ServerNotActive;
import com.sun.corba.se.spi.activation.NoSuchEndPoint;
import com.sun.corba.se.spi.activation.InvalidORBid;
import com.sun.corba.se.spi.activation.Server;
import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
import com.sun.corba.se.spi.ior.IORTemplate ;
import com.sun.corba.se.spi.ior.IOR ;
import com.sun.corba.se.spi.ior.ObjectKey ;
import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
import com.sun.corba.se.spi.ior.IORFactories ;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
import com.sun.corba.se.spi.orb.ORB ;
import com.sun.corba.se.spi.protocol.ForwardException;
import com.sun.corba.se.spi.transport.CorbaTransportManager;
import com.sun.corba.se.spi.logging.CORBALogDomains ;
import com.sun.corba.se.impl.logging.ActivationSystemException ;
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.util.Utility;
public class ServerManagerImpl extends _ServerManagerImplBase
implements BadServerIdHandler
{
// Using HashMap, since synchronization should be done by the calling
// routines
HashMap serverTable;
Repository repository;
CorbaTransportManager transportManager;
int initialPort;
ORB orb;
ActivationSystemException wrapper;
String dbDirName;
boolean debug = false ;
private int serverStartupDelay;
ServerManagerImpl(ORB orb, CorbaTransportManager transportManager,
Repository repository, String dbDirName, boolean debug)
{
this.orb = orb;
wrapper = ActivationSystemException.get( orb, CORBALogDomains.ORBD_ACTIVATOR ) ;
this.transportManager = transportManager; // REVISIT - NOT USED.
this.repository = repository;
this.dbDirName = dbDirName;
this.debug = debug ;
LegacyServerSocketEndPointInfo endpoint =
orb.getLegacyServerSocketManager()
.legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING);
initialPort = ((SocketOrChannelAcceptor)endpoint)
.getServerSocket().getLocalPort();
serverTable = new HashMap(256);
// The ServerStartupDelay is the delay added after the Server registers
// end point information. This is to allow the server to completely
// initialize after ORB is instantiated.
serverStartupDelay = ORBConstants.DEFAULT_SERVER_STARTUP_DELAY;
String delay = System.getProperty( ORBConstants.SERVER_STARTUP_DELAY);
if( delay != null ) {
try {
serverStartupDelay = Integer.parseInt( delay );
} catch ( Exception e ) {
// Just use the default 1000 milliseconds as the default
}
}
Class cls = orb.getORBData( ).getBadServerIdHandler();
if( cls == null ) {
orb.setBadServerIdHandler( this );
} else {
orb.initBadServerIdHandler() ;
}
orb.connect(this);
ProcessMonitorThread.start( serverTable );
}
public void activate(int serverId)
throws ServerAlreadyActive, ServerNotRegistered, ServerHeldDown
{
ServerLocation location;
ServerTableEntry entry;
Integer key = new Integer(serverId);
synchronized(serverTable) {
entry = (ServerTableEntry) serverTable.get(key);
}
if (entry != null && entry.isActive()) {
if (debug)
System.out.println( "ServerManagerImpl: activate for server Id " +
serverId + " failed because server is already active. " +
"entry = " + entry ) ;
throw new ServerAlreadyActive( serverId );
}
// locate the server
try {
// We call getEntry here so that state of the entry is
// checked for validity before we actually go and locate a server
entry = getEntry(serverId);
if (debug)
System.out.println( "ServerManagerImpl: locateServer called with " +
" serverId=" + serverId + " endpointType="
+ IIOP_CLEAR_TEXT.value + " block=false" ) ;
location = locateServer(entry, IIOP_CLEAR_TEXT.value, false);
if (debug)
System.out.println( "ServerManagerImpl: activate for server Id " +
serverId + " found location " +
location.hostname + " and activated it" ) ;
} catch (NoSuchEndPoint ex) {
if (debug)
System.out.println( "ServerManagerImpl: activate for server Id " +
" threw NoSuchEndpoint exception, which was ignored" );
}
}
public void active(int serverId, Server server) throws ServerNotRegistered
{
ServerTableEntry entry;
Integer key = new Integer(serverId);
synchronized (serverTable) {
entry = (ServerTableEntry) serverTable.get(key);
if (entry == null) {
if (debug)
System.out.println( "ServerManagerImpl: active for server Id " +
serverId + " called, but no such server is registered." ) ;
throw wrapper.serverNotExpectedToRegister() ;
} else {
if (debug)
System.out.println( "ServerManagerImpl: active for server Id " +
serverId + " called. This server is now active." ) ;
entry.register(server);
}
}
}
public void registerEndpoints( int serverId, String orbId,
EndPointInfo [] endpointList ) throws NoSuchEndPoint, ServerNotRegistered,
ORBAlreadyRegistered
{
// orbId is ignored for now
ServerTableEntry entry;
Integer key = new Integer(serverId);
synchronized (serverTable) {
entry = (ServerTableEntry) serverTable.get(key);
if (entry == null) {
if (debug)
System.out.println(
"ServerManagerImpl: registerEndpoint for server Id " +
serverId + " called, but no such server is registered." ) ;
throw wrapper.serverNotExpectedToRegister() ;
} else {
if (debug)
System.out.println(
"ServerManagerImpl: registerEndpoints for server Id " +
serverId + " called. This server is now active." ) ;
entry.registerPorts( orbId, endpointList );
}
}
}
public int[] getActiveServers()
{
ServerTableEntry entry;
int[] list = null;
synchronized (serverTable) {
// unlike vectors, list is not synchronized
ArrayList servers = new ArrayList(0);
Iterator serverList = serverTable.keySet().iterator();
try {
while (serverList.hasNext()) {
Integer key = (Integer) serverList.next();
// get an entry
entry = (ServerTableEntry) serverTable.get(key);
if (entry.isValid() && entry.isActive()) {
servers.add(entry);
}
}
} catch (NoSuchElementException e) {
// all done
}
// collect the active entries
list = new int[servers.size()];
for (int i = 0; i < servers.size(); i++) {
entry = (ServerTableEntry) servers.get(i);
list[i] = entry.getServerId();
}
}
if (debug) {
StringBuffer sb = new StringBuffer() ;
for (int ctr=0; ctr<list.length; ctr++) {
sb.append( ' ' ) ;
sb.append( list[ctr] ) ;
}
System.out.println( "ServerManagerImpl: getActiveServers returns" +
sb.toString() ) ;
}
return list;
}
public void shutdown(int serverId) throws ServerNotActive
{
ServerTableEntry entry;
Integer key = new Integer(serverId);
synchronized(serverTable) {
entry = (ServerTableEntry) serverTable.remove(key);
if (entry == null) {
if (debug)
System.out.println( "ServerManagerImpl: shutdown for server Id " +
serverId + " throws ServerNotActive." ) ;
throw new ServerNotActive( serverId );
}
try {
entry.destroy();
if (debug)
System.out.println( "ServerManagerImpl: shutdown for server Id " +
serverId + " completed." ) ;
} catch (Exception e) {
if (debug)
System.out.println( "ServerManagerImpl: shutdown for server Id " +
serverId + " threw exception " + e ) ;
}
}
}
private ServerTableEntry getEntry( int serverId )
throws ServerNotRegistered
{
Integer key = new Integer(serverId);
ServerTableEntry entry = null ;
synchronized (serverTable) {
entry = (ServerTableEntry) serverTable.get(key);
if (debug)
if (entry == null) {
System.out.println( "ServerManagerImpl: getEntry: " +
"no active server found." ) ;
} else {
System.out.println( "ServerManagerImpl: getEntry: " +
" active server found " + entry + "." ) ;
}
if ((entry != null) && (!entry.isValid())) {
serverTable.remove(key);
entry = null;
}
if (entry == null) {
ServerDef serverDef = repository.getServer(serverId);
entry = new ServerTableEntry( wrapper,
serverId, serverDef, initialPort, dbDirName, false, debug);
serverTable.put(key, entry);
entry.activate() ;
}
}
return entry ;
}
private ServerLocation locateServer (ServerTableEntry entry, String endpointType,
boolean block)
throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
{
ServerLocation location = new ServerLocation() ;
// if server location is desired, then wait for the server
// to register back, then return location
ORBPortInfo [] serverORBAndPortList;
if (block) {
try {
serverORBAndPortList = entry.lookup(endpointType);
} catch (Exception ex) {
if (debug)
System.out.println( "ServerManagerImpl: locateServer: " +
"server held down" ) ;
throw new ServerHeldDown( entry.getServerId() );
}
String host =
orb.getLegacyServerSocketManager()
.legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName();
location.hostname = host ;
int listLength;
if (serverORBAndPortList != null) {
listLength = serverORBAndPortList.length;
} else {
listLength = 0;
}
location.ports = new ORBPortInfo[listLength];
for (int i = 0; i < listLength; i++) {
location.ports[i] = new ORBPortInfo(serverORBAndPortList[i].orbId,
serverORBAndPortList[i].port) ;
if (debug)
System.out.println( "ServerManagerImpl: locateServer: " +
"server located at location " +
location.hostname + " ORBid " +
serverORBAndPortList[i].orbId +
" Port " + serverORBAndPortList[i].port) ;
}
}
return location;
}
private ServerLocationPerORB locateServerForORB (ServerTableEntry entry, String orbId,
boolean block)
throws InvalidORBid, ServerNotRegistered, ServerHeldDown
{
ServerLocationPerORB location = new ServerLocationPerORB() ;
// if server location is desired, then wait for the server
// to register back, then return location
EndPointInfo [] endpointInfoList;
if (block) {
try {
endpointInfoList = entry.lookupForORB(orbId);
} catch (InvalidORBid ex) {
throw ex;
} catch (Exception ex) {
if (debug)
System.out.println( "ServerManagerImpl: locateServerForORB: " +
"server held down" ) ;
throw new ServerHeldDown( entry.getServerId() );
}
String host =
orb.getLegacyServerSocketManager()
.legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName();
location.hostname = host ;
int listLength;
if (endpointInfoList != null) {
listLength = endpointInfoList.length;
} else {
listLength = 0;
}
location.ports = new EndPointInfo[listLength];
for (int i = 0; i < listLength; i++) {
location.ports[i] = new EndPointInfo(endpointInfoList[i].endpointType,
endpointInfoList[i].port) ;
if (debug)
System.out.println( "ServerManagerImpl: locateServer: " +
"server located at location " +
location.hostname + " endpointType " +
endpointInfoList[i].endpointType +
" Port " + endpointInfoList[i].port) ;
}
}
return location;
}
public String[] getORBNames(int serverId)
throws ServerNotRegistered
{
try {
ServerTableEntry entry = getEntry( serverId ) ;
return (entry.getORBList());
} catch (Exception ex) {
throw new ServerNotRegistered(serverId);
}
}
private ServerTableEntry getRunningEntry( int serverId )
throws ServerNotRegistered
{
ServerTableEntry entry = getEntry( serverId ) ;
try {
// this is to see if the server has any listeners
ORBPortInfo [] serverORBAndPortList = entry.lookup(IIOP_CLEAR_TEXT.value) ;
} catch (Exception exc) {
return null ;
}
return entry;
}
public void install( int serverId )
throws ServerNotRegistered, ServerHeldDown, ServerAlreadyInstalled
{
ServerTableEntry entry = getRunningEntry( serverId ) ;
if (entry != null) {
repository.install( serverId ) ;
entry.install() ;
}
}
public void uninstall( int serverId )
throws ServerNotRegistered, ServerHeldDown, ServerAlreadyUninstalled
{
ServerTableEntry entry =
(ServerTableEntry) serverTable.get( new Integer(serverId) );
if (entry != null) {
entry =
(ServerTableEntry) serverTable.remove(new Integer(serverId));
if (entry == null) {
if (debug)
System.out.println( "ServerManagerImpl: shutdown for server Id " +
serverId + " throws ServerNotActive." ) ;
throw new ServerHeldDown( serverId );
}
entry.uninstall();
}
}
public ServerLocation locateServer (int serverId, String endpointType)
throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
{
ServerTableEntry entry = getEntry( serverId ) ;
if (debug)
System.out.println( "ServerManagerImpl: locateServer called with " +
" serverId=" + serverId + " endpointType=" +
endpointType + " block=true" ) ;
// passing in entry to eliminate multiple lookups for
// the same entry in some cases
return locateServer(entry, endpointType, true);
}
/** This method is used to obtain the registered ports for an ORB.
* This is useful for custom Bad server ID handlers in ORBD.
*/
public ServerLocationPerORB locateServerForORB (int serverId, String orbId)
throws InvalidORBid, ServerNotRegistered, ServerHeldDown
{
ServerTableEntry entry = getEntry( serverId ) ;
// passing in entry to eliminate multiple lookups for
// the same entry in some cases
if (debug)
System.out.println( "ServerManagerImpl: locateServerForORB called with " +
" serverId=" + serverId + " orbId=" + orbId +
" block=true" ) ;
return locateServerForORB(entry, orbId, true);
}
public void handle(ObjectKey okey)
{
IOR newIOR = null;
ServerLocationPerORB location;
// we need to get the serverid and the orbid from the object key
ObjectKeyTemplate oktemp = okey.getTemplate();
int serverId = oktemp.getServerId() ;
String orbId = oktemp.getORBId() ;
try {
// get the ORBName corresponding to the orbMapid, that was
// first registered by the server
ServerTableEntry entry = getEntry( serverId ) ;
location = locateServerForORB(entry, orbId, true);
if (debug)
System.out.println( "ServerManagerImpl: handle called for server id" +
serverId + " orbid " + orbId) ;
// we received a list of ports corresponding to an ORB in a
// particular server, now retrieve the one corresponding
// to IIOP_CLEAR_TEXT, and for other created the tagged
// components to be added to the IOR
int clearPort = 0;
EndPointInfo[] listenerPorts = location.ports;
for (int i = 0; i < listenerPorts.length; i++) {
if ((listenerPorts[i].endpointType).equals(IIOP_CLEAR_TEXT.value)) {
clearPort = listenerPorts[i].port;
break;
}
}
// create a new IOR with the correct port and correct tagged
// components
IIOPAddress addr = IIOPFactories.makeIIOPAddress( orb,
location.hostname, clearPort ) ;
IIOPProfileTemplate iptemp =
IIOPFactories.makeIIOPProfileTemplate(
orb, GIOPVersion.V1_2, addr ) ;
if (GIOPVersion.V1_2.supportsIORIIOPProfileComponents()) {
iptemp.add(IIOPFactories.makeCodeSetsComponent(orb));
iptemp.add(IIOPFactories.makeMaxStreamFormatVersionComponent());
}
IORTemplate iortemp = IORFactories.makeIORTemplate(oktemp) ;
iortemp.add( iptemp ) ;
newIOR = iortemp.makeIOR(orb, "IDL:org/omg/CORBA/Object:1.0",
okey.getId() );
} catch (Exception e) {
throw wrapper.errorInBadServerIdHandler( e ) ;
}
if (debug)
System.out.println( "ServerManagerImpl: handle " +
"throws ForwardException" ) ;
try {
// This delay is required in case of Server is activated or
// re-activated the first time. Server needs some time before
// handling all the requests.
// (Talk to Ken to see whether there is a better way of doing this).
Thread.sleep( serverStartupDelay );
} catch ( Exception e ) {
System.out.println( "Exception = " + e );
e.printStackTrace();
}
throw new ForwardException(orb, newIOR);
}
public int getEndpoint(String endpointType) throws NoSuchEndPoint
{
return orb.getLegacyServerSocketManager()
.legacyGetTransientServerPort(endpointType);
}
public int getServerPortForType(ServerLocationPerORB location,
String endPointType)
throws NoSuchEndPoint
{
EndPointInfo[] listenerPorts = location.ports;
for (int i = 0; i < listenerPorts.length; i++) {
if ((listenerPorts[i].endpointType).equals(endPointType)) {
return listenerPorts[i].port;
}
}
throw new NoSuchEndPoint();
}
}