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.IOException;
022    import java.util.ArrayList;
023    import java.util.Iterator;
024    import java.util.List;
025    import java.util.Set;
026    
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    import org.apache.geronimo.cli.daemon.DaemonCLParser;
030    import org.apache.geronimo.common.GeronimoEnvironment;
031    import org.apache.geronimo.gbean.AbstractName;
032    import org.apache.geronimo.gbean.AbstractNameQuery;
033    import org.apache.geronimo.gbean.GBeanInfo;
034    import org.apache.geronimo.gbean.GBeanInfoBuilder;
035    import org.apache.geronimo.kernel.Kernel;
036    import org.apache.geronimo.kernel.config.ConfigurationManager;
037    import org.apache.geronimo.kernel.config.ConfigurationUtil;
038    import org.apache.geronimo.kernel.config.DebugLoggingLifecycleMonitor;
039    import org.apache.geronimo.kernel.config.LifecycleMonitor;
040    import org.apache.geronimo.kernel.config.PersistentConfigurationList;
041    import org.apache.geronimo.kernel.repository.Artifact;
042    import org.apache.geronimo.kernel.util.Main;
043    import org.apache.geronimo.system.serverinfo.DirectoryUtils;
044    
045    
046    /**
047     * @version $Rev:385659 $ $Date: 2007-03-07 14:40:07 +1100 (Wed, 07 Mar 2007) $
048     */
049    public class EmbeddedDaemon implements Main {
050        private static final Log log = LogFactory.getLog(EmbeddedDaemon.class);
051    
052        protected final Kernel kernel;
053        private StartupMonitor monitor;
054        private LifecycleMonitor lifecycleMonitor;
055        private List<Artifact> configs = new ArrayList<Artifact>();
056    
057        public EmbeddedDaemon(Kernel kernel) {
058            this.kernel = kernel;
059        }
060        
061        public int execute(Object opaque) {
062            if (! (opaque instanceof DaemonCLParser)) {
063                throw new IllegalArgumentException("Argument type is [" + opaque.getClass() + "]; expected [" + DaemonCLParser.class + "]");
064            }
065            DaemonCLParser parser = (DaemonCLParser) opaque;
066            initializeMonitor(parser);
067            initializeOverride(parser);
068    
069            long start = System.currentTimeMillis();
070    
071            System.out.println("Booting Geronimo Kernel (in Java " + System.getProperty("java.version") + ")...");
072            System.out.flush();
073            
074            // Perform initialization tasks common with the various Geronimo environments
075            GeronimoEnvironment.init();
076            
077            monitor.systemStarting(start);
078            return doStartup();
079        }
080    
081        protected void initializeOverride(DaemonCLParser parser) {
082            String[] override = parser.getOverride();
083            if (null != override) {
084                for (String anOverride : override) {
085                    configs.add(Artifact.create(anOverride));
086                }
087            }
088        }
089    
090        protected void initializeMonitor(DaemonCLParser parser) {
091            if (parser.isVerboseInfo() || parser.isVerboseDebug() || parser.isVerboseTrace() || parser.isNoProgress()) {
092                monitor = new SilentStartupMonitor();
093            } else {
094                if (parser.isLongProgress()) {
095                    monitor = new LongStartupMonitor();
096                } else {
097                    monitor = new ProgressBarStartupMonitor();
098                }
099            }
100            lifecycleMonitor = new DebugLoggingLifecycleMonitor(log);
101        }
102        
103        protected int doStartup() {
104            try {
105                // Check that the tmpdir exists - if not give friendly msg and exit
106                // since we allow it to be configured in geronimo.bat and geronimo.sh
107                // (since 1.0 release) the same way Tomcat allows it to be configured.
108                String tmpDir = System.getProperty("java.io.tmpdir");
109                if (tmpDir == null || (!(new File(tmpDir)).exists()) || (!(new File(tmpDir)).isDirectory())) {
110                    System.err.println("The java.io.tmpdir system property specifies a non-existent directory: "  + tmpDir);
111                    return 1;
112                }
113    
114                // Determine the geronimo installation directory
115                File geronimoInstallDirectory = DirectoryUtils.getGeronimoInstallDirectory();
116                if (geronimoInstallDirectory == null) {
117                    System.err.println("Could not determine geronimo installation directory");
118                    return 1;
119                }
120    
121                int exitCode = initializeKernel();
122                if (0 != exitCode) {
123                    return exitCode;
124                }
125    
126                monitor.systemStarted(kernel);
127    
128                AbstractNameQuery query = new AbstractNameQuery(PersistentConfigurationList.class.getName());
129    
130                if (configs.isEmpty()) {
131                    // --override wasn't used (nothing explicit), see what was running before
132                    Set<AbstractName> configLists = kernel.listGBeans(query);
133                    for (AbstractName configListName : configLists) {
134                        try {
135                            configs.addAll((List<Artifact>) kernel.invoke(configListName, "restore"));
136                        } catch (IOException e) {
137                            System.err.println("Unable to restore last known configurations");
138                            e.printStackTrace();
139                            shutdownKernel();
140                            return 1;
141                        }
142                    }
143                }
144    
145                monitor.foundModules(configs.toArray(new Artifact[configs.size()]));
146    
147                // load the rest of the configurations
148                try {
149                    ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
150                    try {
151                        for (Artifact configID : configs) {
152                            monitor.moduleLoading(configID);
153                            configurationManager.loadConfiguration(configID, lifecycleMonitor);
154                            monitor.moduleLoaded(configID);
155                            monitor.moduleStarting(configID);
156                            configurationManager.startConfiguration(configID, lifecycleMonitor);
157                            monitor.moduleStarted(configID);
158                        }
159                        // the server has finished loading the persistent configuration so inform the gbean
160                        AbstractNameQuery startedQuery = new AbstractNameQuery(ServerStatus.class.getName());
161                        Set statusBeans = kernel.listGBeans(startedQuery);
162                        for(Iterator itr = statusBeans.iterator();itr.hasNext();) {
163                            AbstractName statusName = (AbstractName)itr.next();
164                            ServerStatus status = (ServerStatus)kernel.getGBean(statusName);
165                            if(status != null) {
166                                status.setServerStarted(true);
167                            }
168                        }
169                    } finally {
170                        ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
171                    }
172                } catch (Exception e) {
173                    //Exception caught when starting configurations, starting kernel shutdown
174                    monitor.serverStartFailed(e);
175                    shutdownKernel();
176                    return 1;
177                }
178    
179                // Tell every persistent configuration list that the kernel is now fully started
180                Set<AbstractName> configLists = kernel.listGBeans(query);
181                for (AbstractName configListName : configLists) {
182                    kernel.setAttribute(configListName, "kernelFullyStarted", Boolean.TRUE);
183                }
184    
185                // Startup sequence is finished
186                monitor.startupFinished();
187                monitor = null;
188    
189                // capture this thread until the kernel is ready to exit
190                while (kernel.isRunning()) {
191                    try {
192                        synchronized (kernel) {
193                            kernel.wait();
194                        }
195                    } catch (InterruptedException e) {
196                        // continue
197                    }
198                }
199            } catch (Exception e) {
200                if (monitor != null) {
201                    monitor.serverStartFailed(e);
202                }
203                e.printStackTrace();
204                return 1;
205            }
206            return 0;
207        }
208    
209        protected void shutdownKernel() {
210            try {
211                kernel.shutdown();
212            } catch (Exception e1) {
213                System.err.println("Exception caught during kernel shutdown");
214                e1.printStackTrace();
215            }
216        }
217    
218        protected int initializeKernel() throws Exception {
219            return 0;
220        }
221    
222        public static final GBeanInfo GBEAN_INFO;
223    
224        static {
225            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(EmbeddedDaemon.class, "EmbeddedDaemon");
226            infoFactory.addAttribute("kernel", Kernel.class, false);
227            infoFactory.setConstructor(new String[]{"kernel"});
228            GBEAN_INFO = infoFactory.getBeanInfo();
229        }
230    
231        public static GBeanInfo getGBeanInfo() {
232            return GBEAN_INFO;
233        }
234        
235    }