001: /*
002: * JacORB - a free Java ORB
003: *
004: * Copyright (C) 1999-2004 Gerald Brose
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Library General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Library General Public License for more details.
015: *
016: * You should have received a copy of the GNU Library General Public
017: * License along with this library; if not, write to the Free
018: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
019: *
020: */
021: package org.jacorb.imr;
022:
023: /**
024: * This class is used to start servers on (from the view of the repository)
025: * remote hosts. It has a thread for forwarding output of started servers.
026: *
027: * @author Nicolas Noffke
028: *
029: * $Id: ServerStartupDaemonImpl.java,v 1.18 2007/02/06 23:47:53 andre.spiegel Exp $
030: *
031: */
032:
033: import org.jacorb.util.threadpool.*;
034:
035: import java.net.*;
036: import java.io.*;
037:
038: import org.omg.PortableServer.*;
039:
040: import org.apache.avalon.framework.logger.Logger;
041: import org.apache.avalon.framework.configuration.*;
042:
043: public class ServerStartupDaemonImpl extends
044: org.jacorb.imr.ServerStartupDaemonPOA {
045: private org.omg.CORBA.ORB orb = null;
046: private static final String out_prefix = ">> ";
047:
048: private ThreadPool stdout_pool = null;
049: private ThreadPool stderr_pool = null;
050:
051: private Logger logger;
052:
053: /**
054: * The constructor. It registers this daemon at the repository.
055: */
056: public ServerStartupDaemonImpl(org.omg.CORBA.ORB orb) {
057: this .orb = orb;
058: }
059:
060: public void configure(Configuration myConfiguration)
061: throws ConfigurationException {
062: this .logger = ((org.jacorb.config.Configuration) myConfiguration)
063: .getNamedLogger("jacorb.imr");
064:
065: try {
066: Registration _registration = null;
067:
068: _registration = RegistrationHelper
069: .narrow(orb
070: .resolve_initial_references("ImplementationRepository"));
071: if (_registration == null)
072: throw new ConfigurationException("ImR not found");
073:
074: POA poa = POAHelper.narrow(orb
075: .resolve_initial_references("RootPOA"));
076: poa.the_POAManager().activate();
077:
078: ServerStartupDaemon ssd = ServerStartupDaemonHelper
079: .narrow(poa.servant_to_reference(this ));
080:
081: HostInfo _me = new HostInfo(InetAddress.getLocalHost()
082: .getHostName(), ssd, orb.object_to_string(ssd));
083:
084: _registration.register_host(_me);
085: } catch (Exception e) {
086: throw new ConfigurationException("Caught Exception", e);
087: }
088:
089: stdout_pool = new ThreadPool(
090: (org.jacorb.config.Configuration) myConfiguration,
091: null, new OutputForwarderFactory(
092: new InputStreamSelector() {
093: public InputStream getInputStream(Process p) {
094: return p.getInputStream();
095: }
096: }), //max threads
097: 100, 10);//max idle threads
098:
099: stderr_pool = new ThreadPool(
100: (org.jacorb.config.Configuration) myConfiguration,
101: null, new OutputForwarderFactory(
102: new InputStreamSelector() {
103: public InputStream getInputStream(Process p) {
104: return p.getErrorStream();
105: }
106: }), //max threads
107: 100, 10);//max idle threads
108:
109: }
110:
111: /**
112: * NOT IMPLEMENTED, but currently used for "pinging" purposes.
113: * @return 0 always
114: */
115:
116: public int get_system_load() {
117: // Dummy method, not supported yet.
118: return 0;
119: }
120:
121: /**
122: * This method starts a server on this host as specified by 'command'.
123: *
124: * @param command The server startup command, i.e. the servers class name and
125: * parameters for its main method. The interpreter is inserted automatically.
126: *
127: * @exception ServerStartupFailed
128: * Runtime.exec() failed to execute the command.
129: */
130:
131: public void start_server(String command) throws ServerStartupFailed {
132: try {
133: if (this .logger.isDebugEnabled()) {
134: this .logger.debug("Starting: " + command);
135: }
136:
137: Process _server = Runtime.getRuntime().exec(command);
138:
139: stdout_pool.putJob(_server);
140: stderr_pool.putJob(_server);
141: } catch (Exception _e) {
142: this .logger.error("Server startup failed", _e);
143: throw new ServerStartupFailed(_e.toString());
144: }
145: }
146:
147: /**
148: * main method. Creates a new ServerStartupDaemonImpl instance and runs the orb.
149: **/
150: public static void main(String[] args) {
151: try {
152: org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
153: ServerStartupDaemonImpl _ssd = new ServerStartupDaemonImpl(
154: orb);
155: _ssd.configure(((org.jacorb.orb.ORB) orb)
156: .getConfiguration());
157:
158: orb.run();
159: } catch (Exception _e) {
160: _e.printStackTrace();
161: System.exit(1);
162: }
163:
164: System.exit(0);
165: }
166:
167: /**
168: * Inner class used to forward output of servers, since that would be
169: * invisible otherwise.
170: */
171: private class OutputForwarder implements Consumer {
172: /**
173: * prefix to help distinguish between output of a
174: * started server and output of this SSD
175: */
176: private InputStreamSelector selector = null;
177:
178: public OutputForwarder(InputStreamSelector selector) {
179: this .selector = selector;
180: }
181:
182: public void doWork(Object job) {
183: Process p = (Process) job;
184:
185: BufferedReader _in = new BufferedReader(
186: new InputStreamReader(selector.getInputStream(p)));
187: String _line = null;
188:
189: try {
190: // If we get null from readLine() we assume that the process
191: // has exited. Unfortunately there is no exception thrown
192: // when trying to read from a dead processes output stream.
193: while ((_line = _in.readLine()) != null) {
194: System.out.println(out_prefix + _line);
195: }
196:
197: _in.close();
198: } catch (Exception _e) {
199: logger.debug(
200: "Exception while forwarding server output", _e);
201: }
202:
203: logger.debug("A server process exited");
204: }
205: }//OutputForwarder
206:
207: private interface InputStreamSelector {
208: public InputStream getInputStream(Process p);
209: }
210:
211: private class OutputForwarderFactory implements ConsumerFactory {
212: private InputStreamSelector selector = null;
213:
214: public OutputForwarderFactory(InputStreamSelector selector) {
215: this .selector = selector;
216: }
217:
218: public Consumer create() {
219: return new OutputForwarder(selector);
220: }
221: }
222: } // ServerStartupDaemonImpl
|