Java tutorial
/************************************************************************* * Copyright 2009-2012 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. * * This file may incorporate work covered under the following copyright * and permission notice: * * Software License Agreement (BSD License) * * Copyright (c) 2008, Regents of the University of California * All rights reserved. * * Redistribution and use of this software in source and binary forms, * with or without modification, are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL, * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE, * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS. ************************************************************************/ package com.eucalyptus.bootstrap; import groovy.lang.ExpandoMetaClass; import java.io.PrintStream; import java.lang.Thread.UncaughtExceptionHandler; import java.net.InetAddress; import java.net.NetworkInterface; import java.security.Security; import java.util.Map; import java.util.concurrent.Callable; import org.apache.log4j.Logger; import org.bouncycastle.jce.provider.BouncyCastleProvider; import com.eucalyptus.bootstrap.Bootstrap.Stage; import com.eucalyptus.component.Component; import com.eucalyptus.component.Components; import com.eucalyptus.component.ServiceConfiguration; import com.eucalyptus.empyrean.Empyrean; import com.eucalyptus.records.EventClass; import com.eucalyptus.records.EventRecord; import com.eucalyptus.records.EventType; import com.eucalyptus.records.Logs; import com.eucalyptus.scripting.Groovyness; import com.eucalyptus.system.Capabilities; import com.eucalyptus.system.Threads; import com.eucalyptus.util.Internets; import com.google.common.base.Functions; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; /** * Java entry point from eucalyptus-bootstrap. See {@link Bootstrap} for a detailed explanation of * the system startup procedure. * * <b>IMPORTANT:</b> See {@link #init()} regarding exceptin handling. * * @see Bootstrap * @see SystemBootstrapper#init() */ public class SystemBootstrapper { private static final String SEP = " -- "; static Logger LOG = Logger.getLogger(SystemBootstrapper.class); private static SystemBootstrapper singleton; private static ThreadGroup singletonGroup; public static final PrintStream out = System.out; public static final PrintStream err = System.err; public static SystemBootstrapper getInstance() { synchronized (SystemBootstrapper.class) { if (singleton == null) { singleton = new SystemBootstrapper(); LOG.info("Creating Bootstrapper instance."); } else { LOG.info("Returning Bootstrapper instance."); } } return singleton; } public SystemBootstrapper() { } /** * <b>IMPORTANT NOTE:</b> this is the <b><i>only</i></b> class for which it is acceptable to * {@code catch} or {@code throw} the {@link Throwable} type. See {@link ThreadDeath} for an * explanation of the constraints on * handling {@link Throwable} propagation. * * @see java.lang.ThreadDeath * @param t * @throws Throwable */ private static void handleException(Throwable t) throws Throwable { if (t instanceof BootstrapException) { t.printStackTrace(); LOG.fatal(t, t); throw t; } else { t.printStackTrace(); LOG.fatal(t, t); System.exit(123); } } /** * {@inheritDoc #handleException(Throwable)} * * @return * @throws Throwable */ public boolean init() throws Throwable { ExpandoMetaClass.enableGlobally(); Logs.init(); Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { try { String stack = Joiner.on("\t\n").join(Thread.currentThread().getStackTrace()); LOG.error(stack); LOG.error(e, e); } catch (Exception ex) { try { System.out.println(Joiner.on("\t\n").join(Thread.currentThread().getStackTrace())); e.printStackTrace(); ex.printStackTrace(); } catch (Exception ex1) { System.out.println("Failed because of badness in uncaught exception path."); System.out.println("Thread: " + t.toString()); System.out.println("Exception: " + e.getClass()); System.out.println("Message: " + e.getMessage()); System.out.println("All threads:\n"); for (Map.Entry<Thread, StackTraceElement[]> ent : Thread.getAllStackTraces().entrySet()) { } } } } }); OrderedShutdown.initialize(); BootstrapArgs.init(); if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { if (Security.getProviders().length > 4) { Security.insertProviderAt(new BouncyCastleProvider(), 4); // EUCA-5833 } else { Security.addProvider(new BouncyCastleProvider()); } } try {//GRZE:HACK: need to remove the nss add-on in deb based distros as it breaks ssl. Groovyness.eval( "import sun.security.jca.*; Providers.setProviderList( ProviderList.remove( Providers.@providerList,\"SunPKCS11-NSS\") );"); } catch (Exception ex) { LOG.error(ex, ex); } try { if (!BootstrapArgs.isInitializeSystem()) { Bootstrap.init(); Bootstrap.Stage stage = Bootstrap.transition(); stage.load(); } return true; } catch (Throwable t) { SystemBootstrapper.handleException(t); return false; } } /** * {@inheritDoc #handleException(Throwable)} * * @return * @throws Throwable */ public boolean load() throws Throwable { if (BootstrapArgs.isInitializeSystem()) { try { Bootstrap.initializeSystem(); System.exit(0); } catch (Throwable t) { LOG.error(t, t); System.exit(1); throw t; } } else { SystemBootstrapper.runSystemStages(new Predicate<Stage>() { @Override public boolean apply(Stage input) { input.load(); return true; } }); Bootstrap.applyTransition(Component.State.LOADED, Components.whichCanLoad()); } return true; } /** * NOTE: this is the /only/ class for which it is acceptable to {@code catch} or {@code throw} the * {@link Throwable} type. See {@link ThreadDeath} for an explanation of the constraints on * handling {@link Throwable} propagation. * * @see java.lang.ThreadDeath * @return * @throws Throwable */ public boolean start() throws Throwable { Capabilities.initialize(); SystemBootstrapper.runSystemStages(new Predicate<Stage>() { @Override public boolean apply(Stage input) { input.start(); return true; } }); Bootstrap.applyTransition(Component.State.LOADED, Components.whichCanLoad()); Threads.enqueue(Empyrean.class, SystemBootstrapper.class, new Callable<Boolean>() { @Override public Boolean call() { try { Bootstrap.applyTransition(Component.State.DISABLED, Components.whichCanLoad()); Bootstrap.applyTransition(Component.State.ENABLED, Components.whichCanEnable()); } catch (Exception ex) { LOG.error(ex, ex); } return Boolean.TRUE; } }).get(); try { SystemBootstrapper.printBanner(); } catch (Exception ex) { LOG.error(ex, ex); } return true; } private static void runSystemStages(Predicate<Bootstrap.Stage> exec) throws Throwable { try { // TODO: validation-api /** @NotNull */ Bootstrap.Stage stage = Bootstrap.transition(); do { exec.apply(stage); } while ((stage = Bootstrap.transition()) != null); } catch (Throwable t) { LOG.error(t); Logs.extreme().error(t, t); System.exit(123); } } public String getVersion() { return BillOfMaterials.RequiredFields.VERSION.getValue(); } public boolean check() { return true; } public boolean destroy() { return true; } public boolean stop() throws Exception { LOG.warn("Shutting down Eucalyptus."); EventRecord.here(SystemBootstrapper.class, EventClass.SYSTEM, EventType.SYSTEM_STOP, "SHUT DOWN").info(); return true; } public static void restart() { System.exit(123); } private static native void shutdown(boolean reload); public static native void hello(); private static String printBanner() { String prefix = "\n\t"; String headerHeader = "\n_________________________________________________________\n"; String headerFormat = " %-53.53s"; String headerFooter = "\n_________________________________________________________\n"; String banner = "Started Eucalyptus Version: " + singleton.getVersion() + "\n"; banner += headerHeader + String.format(headerFormat, "System Bootstrap Configuration") + headerFooter; for (Bootstrap.Stage stage : Bootstrap.Stage.values()) { banner += prefix + stage.name() + SEP + stage.describe() .replaceAll("(\\w*)\\w\n", "\1\n" + prefix + stage.name() + SEP).replaceAll("^\\w* ", ""); } banner += headerHeader + String.format(headerFormat, "Component Bootstrap Configuration") + headerFooter; for (Component c : Components.list()) { if (c.getComponentId().isAvailableLocally()) { banner += c.getBootstrapper(); } } banner += headerHeader + String.format(headerFormat, "Local Services") + headerFooter; for (Component c : Components.list()) { if (c.hasLocalService()) { ServiceConfiguration localConfig = c.getLocalServiceConfiguration(); banner += prefix + c.getName() + SEP + localConfig.toString(); banner += prefix + c.getName() + SEP + localConfig.getComponentId().toString(); banner += prefix + c.getName() + SEP + localConfig.lookupState().toString(); } } banner += headerHeader + String.format(headerFormat, "Detected Interfaces") + headerFooter; for (NetworkInterface iface : Internets.getNetworkInterfaces()) { banner += prefix + iface.getDisplayName() + SEP + Lists.transform(iface.getInterfaceAddresses(), Functions.toStringFunction()); for (InetAddress addr : Lists.newArrayList(Iterators.forEnumeration(iface.getInetAddresses()))) { banner += prefix + iface.getDisplayName() + SEP + addr; } } LOG.info(banner); return banner; } }