001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.system.main;
019
020 import java.io.File;
021 import java.io.FileInputStream;
022 import java.io.IOException;
023 import java.util.ArrayList;
024 import java.util.LinkedHashSet;
025 import java.util.List;
026 import java.util.Properties;
027 import java.util.Set;
028
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031 import org.apache.geronimo.cli.daemon.DaemonCLParser;
032 import org.apache.geronimo.common.DeploymentException;
033 import org.apache.geronimo.common.GeronimoEnvironment;
034 import org.apache.geronimo.crypto.EncryptionManager;
035 import org.apache.geronimo.gbean.AbstractName;
036 import org.apache.geronimo.gbean.AbstractNameQuery;
037 import org.apache.geronimo.gbean.GBeanInfo;
038 import org.apache.geronimo.gbean.GBeanInfoBuilder;
039 import org.apache.geronimo.kernel.Kernel;
040 import org.apache.geronimo.kernel.config.ConfigurationManager;
041 import org.apache.geronimo.kernel.config.ConfigurationUtil;
042 import org.apache.geronimo.kernel.config.DebugLoggingLifecycleMonitor;
043 import org.apache.geronimo.kernel.config.InvalidConfigException;
044 import org.apache.geronimo.kernel.config.LifecycleMonitor;
045 import org.apache.geronimo.kernel.config.PersistentConfigurationList;
046 import org.apache.geronimo.kernel.repository.Artifact;
047 import org.apache.geronimo.kernel.util.Main;
048 import org.apache.geronimo.system.serverinfo.DirectoryUtils;
049
050
051 /**
052 * @version $Rev:385659 $ $Date: 2007-03-07 14:40:07 +1100 (Wed, 07 Mar 2007) $
053 */
054 public class EmbeddedDaemon implements Main {
055 private static final Log log = LogFactory.getLog(EmbeddedDaemon.class);
056
057 protected final Kernel kernel;
058 private StartupMonitor monitor;
059 private LifecycleMonitor lifecycleMonitor;
060 private List<Artifact> configs = new ArrayList<Artifact>();
061 static String KEYSTORE_TRUSTSTORE_PASSWORD_FILE = "org.apache.geronimo.keyStoreTrustStorePasswordFile";
062 static String DEFAULT_TRUSTSTORE_KEYSTORE_LOCATION = "/var/security/keystores/geronimo-default";
063 static String GERONIMO_HOME = "org.apache.geronimo.home.dir";
064 static String DEFAULT_KEYSTORE_TRUSTSTORE_PASSWORD_FILE = System.getProperty(GERONIMO_HOME)
065 + "/var/config/config-substitutions.properties";
066
067 public EmbeddedDaemon(Kernel kernel) {
068 this.kernel = kernel;
069 }
070
071 public int execute(Object opaque) {
072 if (!(opaque instanceof DaemonCLParser)) {
073 throw new IllegalArgumentException("Argument type is [" + opaque.getClass() + "]; expected [" + DaemonCLParser.class + "]");
074 }
075 DaemonCLParser parser = (DaemonCLParser) opaque;
076 initializeMonitor(parser);
077 initializeOverride(parser);
078 initializeSecure(parser);
079
080 long start = System.currentTimeMillis();
081
082 System.out.println("Booting Geronimo Kernel (in Java " + System.getProperty("java.version") + ")...");
083 System.out.flush();
084
085 // Perform initialization tasks common with the various Geronimo environments
086 GeronimoEnvironment.init();
087
088 monitor.systemStarting(start);
089 return doStartup();
090 }
091
092 protected void initializeSecure(DaemonCLParser parser)
093 {
094 if(parser.isSecure()){
095 try {
096 Properties props = new Properties();
097
098 String keyStorePassword = null;
099 String trustStorePassword = null;
100
101 FileInputStream fstream = new FileInputStream(System.getProperty(KEYSTORE_TRUSTSTORE_PASSWORD_FILE,
102 DEFAULT_KEYSTORE_TRUSTSTORE_PASSWORD_FILE));
103 props.load(fstream);
104
105 keyStorePassword = (String) EncryptionManager.decrypt(props.getProperty("keyStorePassword"));
106 trustStorePassword = (String) EncryptionManager.decrypt(props.getProperty("trustStorePassword"));
107
108 fstream.close();
109
110 String value = System.getProperty("javax.net.ssl.keyStore", System.getProperty(GERONIMO_HOME)
111 + DEFAULT_TRUSTSTORE_KEYSTORE_LOCATION);
112 String value1 = System.getProperty("javax.net.ssl.trustStore", System.getProperty(GERONIMO_HOME)
113 + DEFAULT_TRUSTSTORE_KEYSTORE_LOCATION);
114 System.setProperty("javax.net.ssl.keyStore", value);
115 System.setProperty("javax.net.ssl.trustStore", value1);
116 System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
117 System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
118 }
119
120 catch(IOException e)
121 {
122 e.printStackTrace();
123 }
124 }
125 }
126 protected void initializeOverride(DaemonCLParser parser) {
127 String[] override = parser.getOverride();
128 if (null != override) {
129 for (String anOverride : override) {
130 configs.add(Artifact.create(anOverride));
131 }
132 }
133 }
134
135 protected void initializeMonitor(DaemonCLParser parser) {
136 if (parser.isVerboseInfo() || parser.isVerboseDebug() || parser.isVerboseTrace() || parser.isNoProgress()) {
137 monitor = new SilentStartupMonitor();
138 } else {
139 if (parser.isLongProgress()) {
140 monitor = new LongStartupMonitor();
141 } else {
142 monitor = new SimpleProgressBarStartupMonitor();
143 }
144 }
145 lifecycleMonitor = new DebugLoggingLifecycleMonitor(log);
146 }
147
148 protected int doStartup() {
149 try {
150 // Check that the tmpdir exists - if not give friendly msg and exit
151 // since we allow it to be configured in geronimo.bat and geronimo.sh
152 // (since 1.0 release) the same way Tomcat allows it to be configured.
153 String tmpDir = System.getProperty("java.io.tmpdir");
154 if (tmpDir == null || (!(new File(tmpDir)).exists()) || (!(new File(tmpDir)).isDirectory())) {
155 System.err.println("The java.io.tmpdir system property specifies a non-existent directory: " + tmpDir);
156 return 1;
157 }
158
159 // Determine the geronimo installation directory
160 File geronimoInstallDirectory = DirectoryUtils.getGeronimoInstallDirectory();
161 if (geronimoInstallDirectory == null) {
162 System.err.println("Could not determine geronimo installation directory");
163 return 1;
164 }
165
166 int exitCode = initializeKernel();
167 if (0 != exitCode) {
168 return exitCode;
169 }
170
171 monitor.systemStarted(kernel);
172
173 AbstractNameQuery query = new AbstractNameQuery(PersistentConfigurationList.class.getName());
174
175 if (configs.isEmpty()) {
176 // --override wasn't used (nothing explicit), see what was running before
177 Set<AbstractName> configLists = kernel.listGBeans(query);
178 for (AbstractName configListName : configLists) {
179 try {
180 configs.addAll((List<Artifact>) kernel.invoke(configListName, "restore"));
181 } catch (IOException e) {
182 System.err.println("Unable to restore last known configurations");
183 e.printStackTrace();
184 shutdownKernel();
185 return 1;
186 }
187 }
188 }
189
190 monitor.foundModules(configs.toArray(new Artifact[configs.size()]));
191
192 // load the rest of the configurations
193 try {
194 ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
195 try {
196 List<Artifact> unloadedConfigs = new ArrayList(configs);
197 int unloadedConfigsCount;
198 do {
199 unloadedConfigsCount = unloadedConfigs.size();
200 LinkedHashSet<Artifact> sorted = configurationManager.sort(unloadedConfigs, lifecycleMonitor);
201 for (Artifact configID : sorted) {
202 monitor.moduleLoading(configID);
203 configurationManager.loadConfiguration(configID, lifecycleMonitor);
204 monitor.moduleLoaded(configID);
205 monitor.moduleStarting(configID);
206 configurationManager.startConfiguration(configID, lifecycleMonitor);
207 monitor.moduleStarted(configID);
208 }
209 } while (unloadedConfigsCount > unloadedConfigs.size());
210 if (!unloadedConfigs.isEmpty()) {
211 throw new InvalidConfigException("Could not locate configs to start: " + unloadedConfigs);
212 }
213 // the server has finished loading the persistent configuration so inform the gbean
214 AbstractNameQuery startedQuery = new AbstractNameQuery(ServerStatus.class.getName());
215 Set<AbstractName> statusBeans = kernel.listGBeans(startedQuery);
216 for (AbstractName statusName : statusBeans) {
217 ServerStatus status = (ServerStatus) kernel.getGBean(statusName);
218 if (status != null) {
219 status.setServerStarted(true);
220 }
221 }
222 } finally {
223 ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
224 }
225 } catch (Exception e) {
226 //Exception caught when starting configurations, starting kernel shutdown
227 monitor.serverStartFailed(e);
228 shutdownKernel();
229 return 1;
230 }
231
232 // Tell every persistent configuration list that the kernel is now fully started
233 Set<AbstractName> configLists = kernel.listGBeans(query);
234 for (AbstractName configListName : configLists) {
235 kernel.setAttribute(configListName, "kernelFullyStarted", Boolean.TRUE);
236 }
237
238 // Startup sequence is finished
239 monitor.startupFinished();
240 monitor = null;
241
242 // capture this thread until the kernel is ready to exit
243 while (kernel.isRunning()) {
244 try {
245 synchronized (kernel) {
246 kernel.wait();
247 }
248 } catch (InterruptedException e) {
249 // continue
250 }
251 }
252 } catch (Exception e) {
253 if (monitor != null) {
254 monitor.serverStartFailed(e);
255 }
256 e.printStackTrace();
257 return 1;
258 }
259 return 0;
260 }
261
262 protected void shutdownKernel() {
263 try {
264 kernel.shutdown();
265 } catch (Exception e1) {
266 System.err.println("Exception caught during kernel shutdown");
267 e1.printStackTrace();
268 }
269 }
270
271 protected int initializeKernel() throws Exception {
272 return 0;
273 }
274
275 public static final GBeanInfo GBEAN_INFO;
276
277 static {
278 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(EmbeddedDaemon.class, "EmbeddedDaemon");
279 infoFactory.addAttribute("kernel", Kernel.class, false);
280 infoFactory.setConstructor(new String[]{"kernel"});
281 GBEAN_INFO = infoFactory.getBeanInfo();
282 }
283
284 public static GBeanInfo getGBeanInfo() {
285 return GBEAN_INFO;
286 }
287
288 }