package org.jacorb.naming; /* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import org.jacorb.config.Configuration; import org.jacorb.config.ConfigurationException; import org.jacorb.imr.util.ImRManager; import org.jacorb.util.ObjectUtil; import org.omg.PortableServer.ForwardRequest; import org.omg.PortableServer.IdAssignmentPolicyValue; import org.omg.PortableServer.LifespanPolicyValue; import org.omg.PortableServer.POA; import org.omg.PortableServer.RequestProcessingPolicyValue; import org.omg.PortableServer.Servant; import org.omg.PortableServer._ServantActivatorLocalBase; import org.slf4j.Logger; /** * The name server application * * @author Gerald Brose, FU Berlin */ public class NameServer { private static org.omg.CORBA.ORB orb = null; private static org.jacorb.config.Configuration configuration = null; /** the specific logger for this component */ private static Logger logger = null; /** the file name int which the IOR will be stored */ private static String fileName = null; private static String filePrefix = "_nsdb"; private static String commandSuffix = ""; /** if this value is != 0, the name server will automatically shut down after the given time */ private static int time_out = 0; static String name_delimiter = "/"; private static boolean printIOR; public static void configure(Configuration myConfiguration) throws ConfigurationException { configuration = (org.jacorb.config.Configuration)myConfiguration; logger = configuration.getLogger("org.jacorb.naming"); printIOR = configuration.getAttributeAsBoolean("jacorb.naming.print_ior", false); time_out = configuration.getAttributeAsInteger("jacorb.naming.time_out",0); fileName = configuration.getAttribute("jacorb.naming.ior_filename", ""); /* which directory to store/load in? */ String directory = configuration.getAttribute("jacorb.naming.db_dir", ""); if( !directory.equals("") ) filePrefix = directory + File.separatorChar + filePrefix; if ( configuration.getAttributeAsBoolean("jacorb.use_imr",false) ) { // don't supply "imr_register", so a ns started by an imr_ssd // won't try to register himself again. String command = configuration.getAttribute("jacorb.java_exec", "") + commandSuffix; ImRManager.autoRegisterServer( orb, "StandardNS", command, ImRManager.getLocalHostName(), true); //edit existing } } /** * The servant manager (servant activator) for the name server POA */ static class NameServantActivatorImpl extends _ServantActivatorLocalBase { private org.omg.CORBA.ORB orb = null; private org.jacorb.config.Configuration configuration = null; private Logger logger = null; public NameServantActivatorImpl(org.omg.CORBA.ORB orb) { this.orb = orb; } public void configure(Configuration myConfiguration) { this.configuration = (org.jacorb.config.Configuration)myConfiguration; this.logger = configuration.getLogger("org.jacorb.naming.activator"); } /** * @return - a servant initialized from a file */ public Servant incarnate( byte[] oid, POA adapter ) throws ForwardRequest { String oidStr = new String(oid); NamingContextImpl n = null; try { File f = new File( filePrefix + oidStr ); if( f.exists() ) { if( logger.isDebugEnabled()) logger.debug("Reading in context state from file"); FileInputStream f_in = new FileInputStream(f); if( f_in.available() > 0 ) { ObjectInputStream in = new ObjectInputStream(f_in); n = (NamingContextImpl)in.readObject(); in.close(); } f_in.close(); } else { if( logger.isDebugEnabled()) logger.debug("No naming context state, starting empty"); } } catch( IOException io ) { if( logger.isDebugEnabled()) logger.debug("File seems corrupt, starting empty"); } catch( java.lang.ClassNotFoundException c ) { if (logger.isErrorEnabled()) { logger.error("Could not read object from file, class not found!"); } throw new RuntimeException ("Could not read object from file, class not found!"); } if( n == null ) { n = new NamingContextImpl(); } n.init(adapter); try { n.configure(configuration); } catch( ConfigurationException ce ) { if (logger.isErrorEnabled()) logger.error("ConfigurationException: " + ce.getMessage()); } return n; } /** * Saves the servant's state in a file */ public void etherealize(byte[] oid, POA adapter, Servant servant, boolean cleanup_in_progress, boolean remaining_activations) { String oidStr = new String(oid); try { File f = new File(filePrefix + oidStr); FileOutputStream fout = new FileOutputStream(f); ObjectOutputStream out = new ObjectOutputStream(fout); /* save state */ out.writeObject(servant); if (logger.isDebugEnabled()) { logger.debug("Saved state for servant " + oidStr); } } catch( IOException io ) { logger.error("Error opening output file " + filePrefix + oidStr, io ); } } } private static void usage() { System.err.println("Usage: java org.jacorb.naming.NameServer [-Djacorb.naming.ior_filename=fname] [-Djacorb.naming.time_out=x][-Djacorb.use_imr=on/off][-Djacorb.naming.purge=on/off ]"); System.exit(1); } /** Main */ public static void main( String args[] ) { try { // TODO: is this correct? needs testing commandSuffix = " org.jacorb.naming.NameServer"; // translate any properties set on the commandline but after the // class name to a properties java.util.Properties argProps = ObjectUtil.argsToProps( args ); java.util.Properties props = new java.util.Properties(); props.put("jacorb.implname", "StandardNS"); /* * by setting the following property, the ORB will * accept client requests targeted at the object with * key "NameService", so more readablee corbaloc URLs * can be used */ props.put("jacorb.orb.objectKeyMap.NameService", "StandardNS/NameServer-POA/_root"); /* any command line properties set _after_ the class name will also be considered */ props.putAll( argProps ); /* intialize the ORB and Root POA */ orb = org.omg.CORBA.ORB.init(args, props); Configuration config = ((org.jacorb.orb.ORB)orb).getConfiguration(); /* configure the name service using the ORB configuration */ configure(config); org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow(orb.resolve_initial_references("RootPOA")); /* create a user defined poa for the naming contexts */ org.omg.CORBA.Policy [] policies = new org.omg.CORBA.Policy[3]; policies[0] = rootPOA.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID); policies[1] = rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT); policies[2] = rootPOA.create_request_processing_policy( RequestProcessingPolicyValue.USE_SERVANT_MANAGER); POA nsPOA = rootPOA.create_POA("NameServer-POA", rootPOA.the_POAManager(), policies); NamingContextImpl.init(orb, rootPOA); NameServer.NameServantActivatorImpl servantActivator = new NameServer.NameServantActivatorImpl( orb ); servantActivator.configure(config); nsPOA.set_servant_manager( servantActivator ); nsPOA.the_POAManager().activate(); for (int i = 0; i < policies.length; i++) policies[i].destroy(); /* export the root context's reference to a file */ byte[] oid = ( new String("_root").getBytes() ); try { org.omg.CORBA.Object obj = nsPOA.create_reference_with_id( oid, "IDL:omg.org/CosNaming/NamingContextExt:1.0"); if( fileName != null && fileName.length() > 0 ) { PrintWriter out = new PrintWriter( new FileOutputStream( fileName ), true ); out.println( orb.object_to_string(obj) ); out.close(); } if (printIOR) { System.out.println("SERVER IOR: " + orb.object_to_string(obj)); } } catch ( Exception e ) { logger.error("unexpected exception", e); throw new RuntimeException(e.getMessage()); } if (logger.isInfoEnabled()) { logger.info("NS up"); } // This shutdown hook fixes the fact that servants aren't being // etherealized because orb.shutdown is not getting called // when ns is killed. Thread shutdownHook = new Thread() { public void run() { logger.info( "shutdownHook invoked" ); orb.shutdown( true ); } }; Runtime.getRuntime().addShutdownHook( shutdownHook ); /* either block indefinitely or time out */ if( time_out == 0 ) orb.run(); else Thread.sleep(time_out); /* shutdown. This will etherealize all servants, thus saving their state */ orb.shutdown( true ); try { Runtime.getRuntime().removeShutdownHook( shutdownHook ); } catch( Exception removeShutdownHookException ) { // removeShutdownHook will throw ignorable illegal state // exception if got here via signal. Ignore exception. } // System.exit(0); } catch( ConfigurationException e ) { e.printStackTrace(); usage(); } catch( Exception e ) { e.printStackTrace(); System.exit(1); } } }