001: package org.jacorb.naming;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.io.File;
024: import java.io.FileInputStream;
025: import java.io.FileOutputStream;
026: import java.io.IOException;
027: import java.io.ObjectInputStream;
028: import java.io.ObjectOutputStream;
029: import java.io.PrintWriter;
030:
031: import org.apache.avalon.framework.configuration.Configuration;
032: import org.apache.avalon.framework.configuration.ConfigurationException;
033: import org.apache.avalon.framework.logger.Logger;
034: import org.jacorb.imr.util.ImRManager;
035: import org.jacorb.util.ObjectUtil;
036: import org.omg.PortableServer.ForwardRequest;
037: import org.omg.PortableServer.IdAssignmentPolicyValue;
038: import org.omg.PortableServer.LifespanPolicyValue;
039: import org.omg.PortableServer.POA;
040: import org.omg.PortableServer.RequestProcessingPolicyValue;
041: import org.omg.PortableServer.Servant;
042: import org.omg.PortableServer._ServantActivatorLocalBase;
043:
044: /**
045: * The name server application
046: *
047: * @author Gerald Brose, FU Berlin
048: * @version $Id: NameServer.java,v 1.36 2006/05/19 08:40:06 alphonse.bendt Exp $
049: */
050:
051: public class NameServer {
052: private static org.omg.CORBA.ORB orb = null;
053: private static org.jacorb.config.Configuration configuration = null;
054:
055: /** the specific logger for this component */
056: private static Logger logger = null;
057:
058: /** the file name int which the IOR will be stored */
059: private static String fileName = null;
060:
061: private static String filePrefix = "_nsdb";
062: private static String commandSuffix = "";
063:
064: /** if this value is != 0, the name server will automatically shut
065: down after the given time */
066: private static int time_out = 0;
067:
068: static String name_delimiter = "/";
069: private static boolean printIOR;
070:
071: public static void configure(Configuration myConfiguration)
072: throws ConfigurationException {
073: configuration = (org.jacorb.config.Configuration) myConfiguration;
074: logger = configuration.getNamedLogger("jacorb.naming");
075:
076: printIOR = configuration.getAttributeAsBoolean(
077: "jacorb.naming.print_ior", false);
078:
079: time_out = configuration.getAttributeAsInteger(
080: "jacorb.naming.time_out", 0);
081:
082: fileName = configuration.getAttribute(
083: "jacorb.naming.ior_filename", "");
084:
085: /* which directory to store/load in? */
086: String directory = configuration.getAttribute(
087: "jacorb.naming.db_dir", "");
088:
089: if (!directory.equals(""))
090: filePrefix = directory + File.separatorChar + filePrefix;
091:
092: if (configuration.getAttribute("jacorb.use_imr", "off").equals(
093: "on")) {
094:
095: // don't supply "imr_register", so a ns started by an imr_ssd
096: // won't try to register himself again.
097:
098: String command = configuration.getAttribute(
099: "jacorb.java_exec", "")
100: + commandSuffix;
101:
102: ImRManager.autoRegisterServer(orb, "StandardNS", command,
103: ImRManager.getLocalHostName(), true); //edit existing
104: }
105: }
106:
107: /**
108: * The servant manager (servant activator) for the name server POA
109: */
110:
111: static class NameServantActivatorImpl extends
112: _ServantActivatorLocalBase {
113: private org.omg.CORBA.ORB orb = null;
114: private org.jacorb.config.Configuration configuration = null;
115: private Logger logger = null;
116:
117: public NameServantActivatorImpl(org.omg.CORBA.ORB orb) {
118: this .orb = orb;
119: }
120:
121: public void configure(Configuration myConfiguration)
122: throws ConfigurationException {
123: this .configuration = (org.jacorb.config.Configuration) myConfiguration;
124: this .logger = configuration
125: .getNamedLogger("jacorb.naming.activator");
126: }
127:
128: /**
129: * @return - a servant initialized from a file
130: */
131:
132: public Servant incarnate(byte[] oid, POA adapter)
133: throws ForwardRequest {
134: String oidStr = new String(oid);
135:
136: NamingContextImpl n = null;
137: try {
138: File f = new File(filePrefix + oidStr);
139: if (f.exists()) {
140: if (logger.isDebugEnabled())
141: logger
142: .debug("Reading in context state from file");
143:
144: FileInputStream f_in = new FileInputStream(f);
145:
146: if (f_in.available() > 0) {
147: ObjectInputStream in = new ObjectInputStream(
148: f_in);
149: n = (NamingContextImpl) in.readObject();
150: in.close();
151: }
152: f_in.close();
153: } else {
154: if (logger.isDebugEnabled())
155: logger
156: .debug("No naming context state, starting empty");
157: }
158:
159: } catch (IOException io) {
160: if (logger.isDebugEnabled())
161: logger.debug("File seems corrupt, starting empty");
162: } catch (java.lang.ClassNotFoundException c) {
163: if (logger.isErrorEnabled()) {
164: logger
165: .error("Could not read object from file, class not found!");
166: }
167: throw new RuntimeException(
168: "Could not read object from file, class not found!");
169: }
170:
171: if (n == null) {
172: n = new NamingContextImpl();
173: }
174:
175: n.init(adapter);
176: try {
177: n.configure(configuration);
178: } catch (ConfigurationException ce) {
179: if (logger.isErrorEnabled())
180: logger.error("ConfigurationException: "
181: + ce.getMessage());
182: }
183: return n;
184: }
185:
186: /**
187: * Saves the servant's state in a file
188: */
189:
190: public void etherealize(byte[] oid, POA adapter,
191: Servant servant, boolean cleanup_in_progress,
192: boolean remaining_activations) {
193: String oidStr = new String(oid);
194:
195: try {
196: File f = new File(filePrefix + oidStr);
197: FileOutputStream fout = new FileOutputStream(f);
198:
199: ObjectOutputStream out = new ObjectOutputStream(fout);
200:
201: /* save state */
202: out.writeObject(servant);
203: if (logger.isDebugEnabled()) {
204: logger.debug("Saved state for servant " + oidStr);
205: }
206: } catch (IOException io) {
207: logger.error("Error opening output file " + filePrefix
208: + oidStr, io);
209: }
210: }
211: }
212:
213: private static void usage() {
214: System.err
215: .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 ]");
216: System.exit(1);
217: }
218:
219: /** Main */
220:
221: public static void main(String args[]) {
222: try {
223: // TODO: is this correct? needs testing
224: commandSuffix = " org.jacorb.naming.NameServer";
225:
226: // translate any properties set on the commandline but after the
227: // class name to a properties
228: java.util.Properties argProps = ObjectUtil
229: .argsToProps(args);
230:
231: java.util.Properties props = new java.util.Properties();
232: props.put("jacorb.implname", "StandardNS");
233:
234: /*
235: * by setting the following property, the ORB will
236: * accept client requests targeted at the object with
237: * key "NameService", so more readablee corbaloc URLs
238: * can be used
239: */
240:
241: props.put("jacorb.orb.objectKeyMap.NameService",
242: "StandardNS/NameServer-POA/_root");
243:
244: /* any command line properties set _after_ the class name will also
245: be considered */
246: props.putAll(argProps);
247:
248: /* intialize the ORB and Root POA */
249: orb = org.omg.CORBA.ORB.init(args, props);
250:
251: Configuration config = ((org.jacorb.orb.ORB) orb)
252: .getConfiguration();
253:
254: /* configure the name service using the ORB configuration */
255: configure(config);
256:
257: org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper
258: .narrow(orb.resolve_initial_references("RootPOA"));
259:
260: /* create a user defined poa for the naming contexts */
261:
262: org.omg.CORBA.Policy[] policies = new org.omg.CORBA.Policy[3];
263:
264: policies[0] = rootPOA
265: .create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID);
266: policies[1] = rootPOA
267: .create_lifespan_policy(LifespanPolicyValue.PERSISTENT);
268:
269: policies[2] = rootPOA
270: .create_request_processing_policy(RequestProcessingPolicyValue.USE_SERVANT_MANAGER);
271:
272: POA nsPOA = rootPOA.create_POA("NameServer-POA", rootPOA
273: .the_POAManager(), policies);
274:
275: NamingContextImpl.init(orb, rootPOA);
276: NameServer.NameServantActivatorImpl servantActivator = new NameServer.NameServantActivatorImpl(
277: orb);
278: servantActivator.configure(config);
279:
280: nsPOA.set_servant_manager(servantActivator);
281: nsPOA.the_POAManager().activate();
282:
283: for (int i = 0; i < policies.length; i++)
284: policies[i].destroy();
285:
286: /* export the root context's reference to a file */
287: byte[] oid = (new String("_root").getBytes());
288: try {
289: org.omg.CORBA.Object obj = nsPOA
290: .create_reference_with_id(oid,
291: "IDL:omg.org/CosNaming/NamingContextExt:1.0");
292:
293: if (fileName != null && fileName.length() > 0) {
294: PrintWriter out = new PrintWriter(
295: new FileOutputStream(fileName), true);
296:
297: out.println(orb.object_to_string(obj));
298: out.close();
299: }
300:
301: if (printIOR) {
302: System.out.println("SERVER IOR: "
303: + orb.object_to_string(obj));
304: }
305: } catch (Exception e) {
306: logger.error("unexpected exception", e);
307: throw new RuntimeException(e.getMessage());
308: }
309:
310: if (logger.isInfoEnabled()) {
311: logger.info("NS up");
312: }
313:
314: // This shutdown hook fixes the fact that servants aren't being
315: // etherealized because orb.shutdown is not getting called
316: // when ns is killed.
317: Thread shutdownHook = new Thread() {
318: public void run() {
319: logger.info("shutdownHook invoked");
320: orb.shutdown(true);
321: }
322: };
323: Runtime.getRuntime().addShutdownHook(shutdownHook);
324:
325: /* either block indefinitely or time out */
326:
327: if (time_out == 0)
328: orb.run();
329: else
330: Thread.sleep(time_out);
331:
332: /* shutdown. This will etherealize all servants, thus
333: saving their state */
334: orb.shutdown(true);
335:
336: try {
337: Runtime.getRuntime().removeShutdownHook(shutdownHook);
338: } catch (Exception removeShutdownHookException) {
339: // removeShutdownHook will throw ignorable illegal state
340: // exception if got here via signal. Ignore exception.
341: }
342:
343: // System.exit(0);
344: } catch (ConfigurationException e) {
345: e.printStackTrace();
346: usage();
347: } catch (Exception e) {
348: e.printStackTrace();
349: System.exit(1);
350: }
351: }
352:
353: }
|