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.InvalidDataException; import com.c2kernel.common.ObjectNotFoundException; import com.c2kernel.entity.CorbaServer; import com.c2kernel.entity.proxy.AgentProxy; import com.c2kernel.entity.proxy.EntityProxyManager; import com.c2kernel.lookup.AgentPath; import com.c2kernel.lookup.LDAPLookup; import com.c2kernel.lookup.LDAPProperties; import com.c2kernel.persistency.ClusterStorageException; import com.c2kernel.persistency.TransactionManager; 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: * * * @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 LDAPLookup mLDAPLookup; static private TransactionManager mStorage; static private EntityProxyManager mProxyManager; static private CorbaServer mCorbaServer; static private CastorXMLUtility mMarshaller; static private AgentProxy mCurrentUser = null; static private ResourceLoader mResource; private Gateway() { } /** * Initialises the Gateway and all of the client objects it holds, with * the exception of the LDAPLookup, 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 LDAPLookup, 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(); 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.runningAsWrapper); } 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); } // if client, run module startup scripts. Otherwise bootstrap will do it after all imports if (!AbstractMain.runningAsWrapper) mModules.runScripts("startup"); } /** * 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() throws InvalidDataException { try { // check top level LDAP contexts mLDAPLookup.install(); // start entity proxy server EntityProxyManager.initServer(); // Init ORB - set various config String serverName = getProperty("ItemServer.name"); if (serverName != null) mC2KProps.put("com.sun.CORBA.ORBServerHost", serverName); String serverPort = 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); //Standard initialisation of the ORB 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 void connect() throws InvalidDataException, ClusterStorageException { LDAPProperties ldapProps = new LDAPProperties(); if( ldapProps.mHost != null && ldapProps.mPort != null && ldapProps.mUser != null && ldapProps.mPassword != null ) { try { mLDAPLookup = new LDAPLookup(ldapProps); } catch (Exception ex) { Logger.error(ex); throw new InvalidDataException("Cannot authenticate. Name and/or password invalid.", ""); } } else { Logger.error("LDAP properties not set for server login."); throw new InvalidDataException("Cannot authenticate with LDAP.", ""); } setup(); } /** * Authenticates a user and returns and AgentProxy on them without overriding the system LDAP context. * Useful for handling multiple users in one context e.g. on a web server * * @param agentName - username * @param agentPassword - password * @return AgentProxy on that user * @throws InvalidDataException * @throws ObjectNotFoundException */ static public AgentProxy login(String agentName, String agentPassword) throws InvalidDataException, ObjectNotFoundException { LDAPProperties ldapProps = new LDAPProperties(); AgentPath agentPath; try { agentPath = mLDAPLookup.getRoleManager().getAgentPath(agentName); } catch (Exception ex) { Logger.error(ex); throw new ObjectNotFoundException("Could not resolve agent", ""); } String agentDN = agentPath.getFullDN(); ldapProps.mUser = agentDN; ldapProps.mPassword = agentPassword; try { LDAPLookup.createConnection(ldapProps); return (AgentProxy)getProxyManager().getProxy(mLDAPLookup.getRoleManager().getAgentPath(agentName)); } catch (Exception ex) { Logger.error(ex); throw new InvalidDataException("Could not log in", ""); } } /** * Logs into the LDAP server with the given username and password, and initialises the lookup. * * @param agentName - username * @param agentPassword - password * @return an AgentProxy on the requested user * @throws InvalidDataException */ static public AgentProxy connect(String agentName, String agentPassword) throws InvalidDataException, ObjectNotFoundException { LDAPProperties ldapProps = new LDAPProperties(); if (ldapProps.mHost!=null && ldapProps.mPort!= null && ldapProps.mLocalPath!=null ) { try { ldapProps.mUser = ""; ldapProps.mPassword = ""; mLDAPLookup = new LDAPLookup(ldapProps); String agentDN = mLDAPLookup.getRoleManager().getAgentPath(agentName).getFullDN(); //found agentDN, try to log in with it ldapProps.mUser = agentDN; ldapProps.mPassword = agentPassword; mLDAPLookup = new LDAPLookup(ldapProps); // find agent proxy AgentPath agentPath = mLDAPLookup.getRoleManager().getAgentPath(agentName); if (agentPath!=null) { setup(); mCurrentUser = (AgentProxy) mProxyManager.getProxy(agentPath); return mCurrentUser; } else { throw new InvalidDataException("The agentDN " +agentDN+ " is invalid.", ""); } } catch (ClusterStorageException e) { throw new InvalidDataException(Language.translate("Error initialising storage")+Language.translate(". See log."), ""); } catch (ObjectNotFoundException e) { throw new ObjectNotFoundException(Language.translate("Invalid username/password"), ""); } catch (Exception e) { throw new InvalidDataException(Language.translate("Could not log in")+": "+Language.translate(e.getMessage()), ""); } } else { throw new InvalidDataException("Cannot log in. Some connection properties are not set.", ""); } } /** * @return the mCurrentUser */ public static AgentProxy getCurrentUser() { return mCurrentUser; } /** * Initializes the storage and proxy manager, called during connect. * * @throws InvalidDataException * @throws ClusterStorageException */ static private void setup() throws InvalidDataException, ClusterStorageException { // Init storages mStorage = new TransactionManager(); mProxyManager = new EntityProxyManager(); } /** * Shuts down all kernel api objects */ public static void close() { // run shutdown module scripts mModules.runScripts("shutdown"); // shut down servers if running if (mCorbaServer != null) mCorbaServer.close(); mCorbaServer = null; // disconnect from storages if (mStorage != null) mStorage.close(); mStorage = null; // disconnect from ldap if (mLDAPLookup != null) mLDAPLookup.disconnect(); mLDAPLookup = null; // shut down proxy manager if (mProxyManager != null) mProxyManager.shutdown(); mProxyManager = null; EntityProxyManager.shutdownServer(); // close log consoles Logger.closeConsole(); // finally, destroy the ORB if (!orbDestroyed) { getORB().destroy(); orbDestroyed = true; } } static public org.omg.CORBA.ORB getORB() { if (orbDestroyed) throw new RuntimeException("Gateway has been closed. ORB is destroyed."); if (mORB == null) mORB = org.omg.CORBA.ORB.init(new String[0], mC2KProps); return mORB; } static public LDAPLookup getLDAPLookup() { return mLDAPLookup; } 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 EntityProxyManager getProxyManager() { return mProxyManager; } 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"; } } }