package com.c2kernel.process;
/**
* @version $Revision: 1.17 $ $Date: 2005/10/12 12:51:54 $
* @author $Author: abranson $
*/
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.Properties;
import com.c2kernel.common.CannotManageException;
import com.c2kernel.common.InvalidDataException;
import com.c2kernel.common.ObjectNotFoundException;
import com.c2kernel.entity.CorbaServer;
import com.c2kernel.entity.proxy.AgentProxy;
import com.c2kernel.entity.proxy.ProxyManager;
import com.c2kernel.entity.proxy.ProxyServer;
import com.c2kernel.lookup.AgentPath;
import com.c2kernel.lookup.Lookup;
import com.c2kernel.lookup.LookupManager;
import com.c2kernel.persistency.ClusterStorageException;
import com.c2kernel.persistency.NextKeyManager;
import com.c2kernel.persistency.TransactionManager;
import com.c2kernel.process.auth.Authenticator;
import com.c2kernel.process.module.ModuleManager;
import com.c2kernel.process.resource.Resource;
import com.c2kernel.process.resource.ResourceLoader;
import com.c2kernel.utils.CastorXMLUtility;
import com.c2kernel.utils.FileStringUtility;
import com.c2kernel.utils.Language;
import com.c2kernel.utils.Logger;
import com.c2kernel.utils.ObjectProperties;
/**************************************************************************
* The Gateway is the central object of a CRISTAL process. It initializes,
* maintains and shuts down every other subsystem in both the client and the
* server.
*
* Child objects:
*
* - Lookup - Provides access to the CRISTAL directory. Find or
* search for Items or Agents.
*
- EntityProxyManager - Gives a local proxy object for Entities found
* in LDAP. Execute activities in Items, query or subscribe to Entity data.
*
- TransactionManager - Access to the configured CRISTAL databases
*
- CorbaServer - Manages the memory pool of active Entities
*
- mORB - the Orbacus CORBA ORB
*
*
* @author $Author: abranson $ $Date: 2005/10/12 12:51:54 $
* @version $Revision: 1.17 $
**************************************************************************/
public class Gateway
{
static private ObjectProperties mC2KProps;
static private ModuleManager mModules;
static private org.omg.CORBA.ORB mORB;
static private boolean orbDestroyed = false;
static private Lookup mLookup;
static private LookupManager mLookupManager = null;
static private NextKeyManager mNextKeyManager;
static private TransactionManager mStorage;
static private ProxyManager mProxyManager;
static private ProxyServer mProxyServer;
static private CorbaServer mCorbaServer;
static private CastorXMLUtility mMarshaller;
static private ResourceLoader mResource;
private Gateway() { }
/**
* Initialises the Gateway and all of the client objects it holds, with
* the exception of the Lookup, which is initialised during connect()
*
* @param props - java.util.Properties containing all application properties.
* If null, the java system properties are used
* @throws InvalidDataException - invalid properties caused a failure in initialisation
*/
static public void init(Properties props) throws InvalidDataException {
init(props, null);
}
/**
* Initialises the Gateway and all of the client objects it holds, with
* the exception of the Lookup, which is initialised during connect()
*
* @param props - java.util.Properties containing all application properties.
* If null, the java system properties are used
* @param res - ResourceLoader for the kernel to use to resolve all class resource requests
* such as for bootstrap descriptions and version information
* @throws InvalidDataException - invalid properties caused a failure in initialisation
*/
static public void init(Properties props, ResourceLoader res) throws InvalidDataException {
// Init properties & resources
mC2KProps = new ObjectProperties();
orbDestroyed = false;
mResource = res;
if (mResource == null) mResource = new Resource();
// report version info
Logger.msg("Kernel version: "+getKernelVersion());
// load kernel mapfiles
try {
mMarshaller = new CastorXMLUtility(mResource.getKernelResourceURL("mapFiles/"));
} catch (MalformedURLException e1) {
throw new InvalidDataException("Invalid Resource Location", "");
}
// init module manager
try {
mModules = new ModuleManager(mResource.getModuleDefURLs(), AbstractMain.isServer);
} catch (Exception e) {
Logger.error(e);
throw new InvalidDataException("Could not load module definitions.", "");
}
// merge in module props
Properties moduleProperties = mModules.getAllModuleProperties();
for (Enumeration> e = moduleProperties.propertyNames(); e.hasMoreElements();) {
String propName = (String)e.nextElement();
mC2KProps.put(propName, moduleProperties.get(propName));
}
// Overwrite with argument props
if (props != null) mC2KProps.putAll(props);
// dump properties
dumpC2KProps(7);
//Initialise language file
String languageFile = getProperty("language.file");
if (languageFile != null && languageFile.length() > 0) {
Language.isTranlated=true;
Language.mTableOfTranslation = FileStringUtility.loadLanguageFile(languageFile);
}
}
/**
* Makes this process capable of creating and managing server entities. Runs the
* bootstrap to create the root LDAP contexts, initialises the CORBA server and
* time-out manager.
*
* @throws InvalidDataException - error initialising
*/
static public void startServer(Authenticator auth) throws InvalidDataException, CannotManageException {
try {
// check top level directory contexts
if (mLookup instanceof LookupManager) {
mLookupManager = (LookupManager)mLookup;
mLookupManager.initializeDirectory();
}
else {
throw new CannotManageException("Lookup implementation is not a LookupManager. Cannot write to directory");
}
// init next key manager
mNextKeyManager = (NextKeyManager)mC2KProps.getInstance("NextKeyManager");
mNextKeyManager.open(auth);
// start entity proxy server
mProxyServer = new ProxyServer(mC2KProps.getProperty("ItemServer.name"));
// Init ORB - set various config
String serverName = mC2KProps.getProperty("ItemServer.name");
if (serverName != null)
mC2KProps.put("com.sun.CORBA.ORBServerHost", serverName);
String serverPort = mC2KProps.getProperty("ItemServer.iiop", "1500");
mC2KProps.put("com.sun.CORBA.ORBServerPort", serverPort);
//TODO: externalize this (or replace corba completely)
mC2KProps.put("com.sun.CORBA.POA.ORBServerId", "1");
mC2KProps.put("com.sun.CORBA.POA.ORBPersistentServerPort", serverPort);
mC2KProps.put("com.sun.CORBA.codeset.charsets", "0x05010001, 0x00010109"); // need to force UTF-8 in the Sun ORB
mC2KProps.put("com.sun.CORBA.codeset.wcharsets", "0x00010109, 0x05010001");
//Standard initialisation of the ORB
orbDestroyed = false;
mORB = org.omg.CORBA.ORB.init(new String[0], mC2KProps);
Logger.msg("Gateway.init() - ORB initialised. ORB is " + mORB.getClass().getName() );
// start corba server components
mCorbaServer = new CorbaServer();
// start checking bootstrap & module items
Bootstrap.run();
} catch (Exception ex) {
Logger.error(ex);
Logger.die("Exception starting server components. Shutting down.");
}
System.out.println("Server '"+Gateway.getCentreId()+"' initialised.");
}
public static ModuleManager getModuleManager() {
return mModules;
}
/**
* Connects to the LDAP server in an administrative context - using the admin username and
* password given in the LDAP.user and LDAP.password props of the kernel properties.
*
* @throws InvalidDataException - bad params
* @throws ClusterStorageException - error starting storages
*/
static public Authenticator connect()
throws InvalidDataException,
ClusterStorageException
{
try {
Authenticator auth = (Authenticator)mC2KProps.getInstance("Authenticator");
auth.authenticate("System");
mLookup = (Lookup)mC2KProps.getInstance("Lookup");
mLookup.open(auth);
mStorage = new TransactionManager(auth);
mProxyManager = new ProxyManager();
return auth;
} catch (Exception ex) {
Logger.error(ex);
throw new InvalidDataException("Cannot connect server process. Please check config.", "");
}
}
/**
* Logs in with the given username and password, and initialises the lookup, storage and proxy manager.
*
* @param agentName - username
* @param agentPassword - password
* @return an AgentProxy on the requested user
* @throws InvalidDataException
* @throws ClusterStorageException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
static public AgentProxy connect(String agentName, String agentPassword, String resource)
throws InvalidDataException, ObjectNotFoundException, ClusterStorageException, InstantiationException, IllegalAccessException, ClassNotFoundException
{
Authenticator auth = (Authenticator)mC2KProps.getInstance("Authenticator");
if (!auth.authenticate(agentName, agentPassword, resource))
throw new InvalidDataException("Login failed", "");
mLookup = (Lookup)mC2KProps.getInstance("Lookup");
mLookup.open(auth);
mStorage = new TransactionManager(auth);
mProxyManager = new ProxyManager();
// find agent proxy
AgentPath agentPath = mLookup.getAgentPath(agentName);
AgentProxy userProxy = (AgentProxy) mProxyManager.getProxy(agentPath);
userProxy.setAuthObj(auth);
// Run module startup scripts. Server does this during bootstrap
mModules.setUser(userProxy);
mModules.runScripts("startup");
return userProxy;
}
static public AgentProxy connect(String agentName, String agentPassword)
throws InvalidDataException, ObjectNotFoundException, ClusterStorageException, InstantiationException, IllegalAccessException, ClassNotFoundException
{
return connect(agentName, agentPassword, null);
}
/**
* Shuts down all kernel api objects
*/
public static void close()
{
// run shutdown module scripts
if (mModules != null)
mModules.runScripts("shutdown");
// shut down servers if running
if (mCorbaServer != null)
mCorbaServer.close();
mCorbaServer = null;
// close next key manager
if (mNextKeyManager != null)
mNextKeyManager.close();
mNextKeyManager = null;
// disconnect from storages
if (mStorage != null)
mStorage.close();
mStorage = null;
// disconnect from ldap
if (mLookup != null)
mLookup.close();
mLookup = null;
mLookupManager = null;
// shut down proxy manager & server
if (mProxyManager != null)
mProxyManager.shutdown();
if (mProxyServer != null)
mProxyServer.shutdownServer();
mProxyManager = null;
mProxyServer = null;
// close log consoles
Logger.closeConsole();
// finally, destroy the ORB
if (!orbDestroyed) {
getORB().destroy();
orbDestroyed = true;
}
// clean up remaining objects
mModules = null;
mResource = null;
mMarshaller = null;
mC2KProps = null;
}
static public org.omg.CORBA.ORB getORB()
{
if (orbDestroyed) throw new RuntimeException("Gateway has been closed. ORB is destroyed.");
if (mORB == null) {
mC2KProps.put("com.sun.CORBA.codeset.charsets", "0x05010001, 0x00010109"); // need to force UTF-8 in the Sun ORB
mC2KProps.put("com.sun.CORBA.codeset.wcharsets", "0x00010109, 0x05010001");
mORB = org.omg.CORBA.ORB.init(new String[0], mC2KProps);
}
return mORB;
}
static public Lookup getLookup()
{
return mLookup;
}
static public LookupManager getLookupManager() throws CannotManageException
{
if (mLookupManager == null)
throw new CannotManageException("No Lookup Manager created. Not a server process.", "");
else
return mLookupManager;
}
static public CorbaServer getCorbaServer()
{
return mCorbaServer;
}
static public TransactionManager getStorage()
{
return mStorage;
}
static public CastorXMLUtility getMarshaller()
{
return mMarshaller;
}
static public ResourceLoader getResource()
{
return mResource;
}
static public ProxyManager getProxyManager()
{
return mProxyManager;
}
public static ProxyServer getProxyServer() {
return mProxyServer;
}
static public String getCentreId() {
return getProperty("LocalCentre");
}
@Deprecated
static public String getProperty(String propName) {
return getProperty(propName, null);
}
@Deprecated
static public String getProperty(String propName, String defaultValue) {
if (mC2KProps == null) return defaultValue;
return mC2KProps.getProperty(propName, defaultValue);
}
@Deprecated
static public void setProperty(String propName, String propValue) {
if (mC2KProps == null) return;
mC2KProps.put(propName, propValue);
}
static public Enumeration> propertyNames() {
return mC2KProps.propertyNames();
}
static public void dumpC2KProps(int logLevel) {
if (!Logger.doLog(logLevel)) return;
mC2KProps.dumpProps(logLevel);
}
static public ObjectProperties getProperties() {
return mC2KProps;
}
static public String getKernelVersion() {
try {
return mResource.getTextResource(null, "textFiles/version.txt");
} catch (Exception ex) {
return "No version info found";
}
}
public static NextKeyManager getNextKeyManager() {
return mNextKeyManager;
}
}