/*************************************************************************
* 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 java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import com.eucalyptus.binding.BindingCache;
import com.eucalyptus.component.Component;
import com.eucalyptus.component.ComponentId;
import com.eucalyptus.component.ComponentIds;
import com.eucalyptus.component.Components;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
import com.eucalyptus.empyrean.Empyrean;
import com.eucalyptus.empyrean.EmpyreanService;
import com.eucalyptus.records.EventRecord;
import com.eucalyptus.records.EventType;
import com.eucalyptus.records.Logs;
import com.eucalyptus.scripting.Groovyness;
import com.eucalyptus.system.Threads;
import com.eucalyptus.system.Threads.ThreadPool;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.LogUtil;
import com.eucalyptus.util.fsm.OrderlyTransitionException;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* Mechanism for setting up and progressing through the sequence of stages the system goes through
* during bootstrap. The bootstrap process consists
* of two phases:
*
* <ol>
* <li><b>load()</b>: {@link SystemBootstrapper#load()}</li>
* <li><b>start()</b> {@link SystemBootstrapper#start()}</li>
* </ol>
*
* Each phase consists of iterating through each {@link Bootstrap.Stage} and executing the
* associated bootstrappers accordingly.
* Implementors of {@link Bootstrapper} must declare which {@link Bootstrap.Stage} they are to be
* executed by specifying the {@link RunDuring} annotation.
*
* NOTE: It is worth noting that the {@link #start()}-phase is <b>NOT</b> executed for the
* {@link EmpyreanService.Stage.PrivilegedConfiguration} stage. Since
* privileges must be dropped
* after {@link EmpyreanService.Stage.PrivilegedConfiguration}.{@link #load()} the bootstrappers
* would no
* longer have the indicated privileges.
*
* After a call to {@link #transition()} the current stage can be obtained from
* {@link #getCurrentStage()}.
*
* Once {@link EmpyreanService.Stage.Final} is reached for {@link SystemBootstrapper#load()} the
* {@link #getCurrentStage()} is reset to be {@link EmpyreanService.Stage.SystemInit} and
* {@link SystemBootstrapper#start()} proceeds. Upon completing {@link SystemBootstrapper#start()}
* the state
* forever remains {@link EmpyreanService.Stage.Final}.
* return {@link EmpyreanService.Stage.Final}.
*
* @see Bootstrap.Stage
* @see PrivilegedConfiguration#start()
* @see SystemBootstrapper#init()
* @see SystemBootstrapper#load()
* @see SystemBootstrapper#start()
*/
public class Bootstrap {
static Logger LOG = Logger.getLogger( Bootstrap.class );
@Target( { ElementType.TYPE,
ElementType.FIELD } )
@Retention( RetentionPolicy.RUNTIME )
public @interface Discovery {
/**
* Filter arguments to {@link Predicate#apply(Object argument)} by enforcing that {@link
* Iterables#any(Iterable #value( ), Predicate Classes#assignable())} is true (where assignable
* checks {@link Class#isAssignableFrom(Class argument)}) is {@code true} for the
* {@code argument}
*
* @return
*/
Class[] value( ) default {};
double priority( ) default 0.99d;
/**
* Filter arguments to {@link Predicate#apply(Object argument)} by enforcing that {@link
* Iterables#any(Iterable #annotations( ), Predicate Classes#assignable())} is true (where assignable
* checks {@link Ats#from(Object argument)#has(Class #annotations( ))}) is {@code true} for the
* {@code argument}
*
* @return
*/
Class[] annotations( );
}
/**
* Mechanism for setting up and progressing through the sequence of stages the system goes through
* during bootstrap. The bootstrap process consists
* of two phases:
* <ol>
* <li><b>load()</b>: {@link SystemBootstrapper#load()}</li>
* <li><b>start()</b> {@link SystemBootstrapper#start()}</li>
* </ol>
* Each phase consists of iterating through each {@link Bootstrap.Stage} and executing the
* associated bootstrappers accordingly.
*
* NOTE: It is worth noting that the {@link #start()}-phase is <b>NOT</b> executed for the
* {@link EmpyreanService.Stage.PrivilegedConfiguration} stage. Since
* privileges must be dropped
* after {@link EmpyreanService.Stage.PrivilegedConfiguration}.{@link #load()} the bootstrappers
* would no
* longer have the indicated privileges.
*
* Once {@link EmpyreanService.Stage.Final} is reached for {@link SystemBootstrapper#load()} the
* {@link #getCurrentStage()} is reset to be {@link EmpyreanService.Stage.SystemInit} and
* {@link SystemBootstrapper#start()} proceeds. Upon completing {@link SystemBootstrapper#start()}
* the state
* forever remains {@link EmpyreanService.Stage.Final}.
* return {@link EmpyreanService.Stage.Final}.
*
* @see PrivilegedConfiguration#start()
* @see SystemBootstrapper#init()
* @see SystemBootstrapper#load()
* @see SystemBootstrapper#start()
*/
public enum Stage {
SystemInit {
/**
* Nothing is allowed to execute during the start phase of this {@link Bootstrap.Stage}
*
* @see com.eucalyptus.bootstrap.Bootstrap.Stage#start()
*/
@Override
public void start( ) {
for ( Bootstrapper b : this.bootstrappers ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, this.name( ), "SKIPPING start()", b.getClass( ).getCanonicalName( ) ).warn( );
}
}
},
PrivilegedConfiguration {
/**
* Nothing is allowed to execute during the start phase of this {@link Bootstrap.Stage}
*
* @see com.eucalyptus.bootstrap.Bootstrap.Stage#start()
*/
@Override
public void start( ) {
for ( Bootstrapper b : this.bootstrappers ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, this.name( ), "SKIPPING start()", b.getClass( ).getCanonicalName( ) ).warn( );
}
}
},
UnprivilegedConfiguration,
SystemCredentialsInit, /* <-- this means system credentials, not user. */
RemoteConfiguration,
DatabaseInit,
UpgradeDatabase,
PoolInit,
PersistenceInit,
RemoteDbPoolInit,
SystemAccountsInit,
RemoteServicesInit,
UserCredentialsInit,
CloudServiceInit,
Final;
public static List<Stage> list( ) {
return Arrays.asList( Stage.values( ) );
}
protected final Set<Bootstrapper> bootstrappers = new ConcurrentSkipListSet<Bootstrapper>( );
private final Set<Bootstrapper> disabledBootstrappers = new ConcurrentSkipListSet<Bootstrapper>( );
void addBootstrapper( Bootstrapper b ) {
if ( this.bootstrappers.contains( b ) ) {
throw BootstrapException.throwFatal( "Duplicate bootstrapper registration: " + b.getClass( ).toString( ) );
} else {
this.bootstrappers.add( b );
}
}
void skipBootstrapper( Bootstrapper b ) {
if ( this.disabledBootstrappers.contains( b ) ) {
throw BootstrapException.throwFatal( "Duplicate bootstrapper registration: " + b.getClass( ).toString( ) );
} else {
this.disabledBootstrappers.add( b );
}
}
private void printAgenda( ) {
if ( !this.bootstrappers.isEmpty( ) ) {
LOG.info( LogUtil.header( "Bootstrap stage: " + this.name( )
+ "."
+ ( !Bootstrap.starting
? "load()"
: "start()" ) ) );
LOG.debug( Joiner.on( " " ).join( this.name( ) + " bootstrappers: ", this.bootstrappers ) );
}
}
public void updateBootstrapDependencies( ) {
Iterable<Bootstrapper> currBootstrappers = Iterables.concat( Lists.newArrayList( this.bootstrappers ),
Lists.newArrayList( this.disabledBootstrappers ) );
this.bootstrappers.clear( );
this.disabledBootstrappers.clear( );
for ( Bootstrapper bootstrapper : currBootstrappers ) {
try {
if ( bootstrapper.checkLocal( ) && bootstrapper.checkRemote( ) ) {
this.enableBootstrapper( bootstrapper );
} else {
this.disableBootstrapper( bootstrapper );
}
} catch ( Exception ex ) {
LOG.error( ex, ex );
}
}
}
private void enableBootstrapper( Bootstrapper bootstrapper ) {
Logs.exhaust( ).trace( EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_MARK_ENABLED, "stage=" + this.toString( ), bootstrapper.toString( ) ) );
this.disabledBootstrappers.remove( bootstrapper );
this.bootstrappers.add( bootstrapper );
}
private void disableBootstrapper( Bootstrapper bootstrapper ) {
Logs.exhaust( ).trace( EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_MARK_DISABLED, "stage=" + this.toString( ), bootstrapper.toString( ) ) );
this.bootstrappers.remove( bootstrapper );
this.disabledBootstrappers.add( bootstrapper );
}
public void load( ) {
this.updateBootstrapDependencies( );
this.printAgenda( );
for ( Bootstrapper b : this.bootstrappers ) {
try {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_LOAD, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
boolean result = b.load( );
if ( !result ) {
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " returned 'false' from load( ): terminating bootstrap." );
}
} catch ( Exception e ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ERROR, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " threw an error in load( ): "
+ e.getMessage( ), e );
}
}
}
public void start( ) {
this.updateBootstrapDependencies( );
this.printAgenda( );
for ( Bootstrapper b : this.bootstrappers ) {
try {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_START, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
boolean result = b.start( );
if ( !result ) {
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " returned 'false' from start( ): terminating bootstrap." );
}
} catch ( Exception e ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ERROR, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " threw an error in start( ): "
+ e.getMessage( ), e );
}
}
}
public String describe( ) {
StringBuffer buf = new StringBuffer( this.name( ) ).append( " " );
for ( Bootstrapper b : this.bootstrappers ) {
buf.append( b.getClass( ).getSimpleName( ) ).append( " " );
}
return buf.append( "\n" ).toString( );
}
}
static Boolean loading = false;
private static Boolean starting = false;
private static Boolean finished = false;
private static Stage currentStage = Stage.SystemInit;
static volatile Boolean shutdown = false;
/**
* @return Bootstrap.currentStage
*/
public static Stage getCurrentStage( ) {
return currentStage;
}
/**
* Find and run all discovery implementations (see {@link ServiceJarDiscovery}).
*
* First, find all instantiable descendants of {@link ServiceJarDiscovery}.
* Second, execute each discovery implementation.
* <b>NOTE:</b> This method finds the available bootstrappers but does not evaluate their
* dependency constraints.
*/
private static void doDiscovery( ) {
ServiceJarDiscovery.processLibraries( );
ServiceJarDiscovery.runDiscovery( );
}
/**
* TODO: DOCUMENT Bootstrap.java
*/
public static void initBootstrappers( ) {
for ( Bootstrap.Stage stage : Stage.values( ) ) {
stage.bootstrappers.clear( );
stage.disabledBootstrappers.clear( );
}
for ( Bootstrapper bootstrap : BootstrapperDiscovery.getBootstrappers( ) ) {//these have all been checked at discovery time
try {
Class<ComponentId> compType;
String bc = bootstrap.getClass( ).getCanonicalName( );
Bootstrap.Stage stage = bootstrap.getBootstrapStage( );
compType = bootstrap.getProvides( );
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_INIT, stage.name( ), bc, "component=" + compType.getSimpleName( ) ).info( );
if ( ComponentId.class.isAssignableFrom( compType ) && !Empyrean.class.equals( compType )
&& !ComponentId.class.equals( compType ) ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ADDED, stage.name( ), bc, "component=" + compType.getSimpleName( ) ).info( );
Components.lookup( compType ).addBootstrapper( bootstrap );
} else if ( Bootstrap.checkDepends( bootstrap ) ) {
if ( Empyrean.class.equals( compType ) ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ADDED, stage.name( ), bc, "component=" + compType.getSimpleName( ) ).info( );
stage.addBootstrapper( bootstrap );
} else if ( ComponentId.class.equals( compType ) ) {
for ( Component c : Components.list( ) ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ADDED, stage.name( ), bc, "component=" + c.getName( ) ).info( );
c.addBootstrapper( bootstrap );
}
}
} else {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, stage.name( ), bc, "component=" + compType.getSimpleName( ),
"localDepends=" + bootstrap.checkLocal( ), "remoteDepends=" + bootstrap.checkRemote( ) ).info( );
}
} catch ( Exception ex ) {
LOG.error( ex, ex );
}
}
}
private static boolean checkDepends( Bootstrapper bootstrap ) {
String bc = bootstrap.getClass( ).getCanonicalName( );
if ( bootstrap.checkLocal( ) && bootstrap.checkRemote( ) ) {
return true;
} else {
if ( !bootstrap.checkLocal( ) ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, currentStage.name( ), bc, "DependsLocal",
bootstrap.getDependsLocal( ).toString( ) ).info( );
} else if ( !bootstrap.checkRemote( ) ) {
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, currentStage.name( ), bc, "DependsRemote",
bootstrap.getDependsRemote( ).toString( ) ).info( );
}
return false;
}
}
/**
* Subsequent calls to {@link #transition()} trigger the transition through the two-phase
* (load/start) iteration through the {@link Bootstrap.Stage}s.
*
* After a call to {@link #transition()} the current stage can be obtained from
* {@link #getCurrentStage()}.
*
* Once {@link EmpyreanService.Stage.Final} is reached for {@link SystemBootstrapper#load()} the
* {@link #getCurrentStage()} is reset to be {@link EmpyreanService.Stage.SystemInit} and
* {@link SystemBootstrapper#start()} proceeds. Upon completing {@link SystemBootstrapper#start()}
* the state
* forever remains {@link EmpyreanService.Stage.Final}.
* return {@link EmpyreanService.Stage.Final}.
*
* @return currentStage either the same as before, or the next {@link Bootstrap.Stage}.
*/
public static synchronized Stage transition( ) {
if ( currentStage == Stage.SystemInit && !loading
&& !starting
&& !finished ) {
loading = true;
starting = false;
finished = false;
} else if ( currentStage != null ) {
LOG.info( LogUtil.header( "Bootstrap stage completed: " + currentStage.toString( ) ) );
if ( Stage.Final.equals( currentStage ) ) {
currentStage = null;
if ( loading && !starting
&& !finished ) {
loading = true;
starting = true;
finished = false;
} else if ( loading && starting
&& !finished ) {
loading = true;
starting = true;
finished = true;
}
return currentStage;
}
}
int currOrdinal = currentStage != null
? currentStage.ordinal( )
: -1;
for ( int i = currOrdinal + 1; i <= Stage.Final.ordinal( ); i++ ) {
currentStage = Stage.values( )[i];
if ( currentStage.bootstrappers.isEmpty( ) ) {
LOG.trace( LogUtil.subheader( "Bootstrap stage skipped: " + currentStage.toString( ) ) );
continue;
} else {
return currentStage;
}
}
return currentStage;
}
public static Boolean isLoaded( ) {
return starting;
}
public static Boolean isOperational( ) {
return isFinished( ) && !isShuttingDown( );
}
public static void awaitFinished( ) {
awaitFinished( Long.MAX_VALUE );
}
public static void awaitFinished( Long millis ) {
try {
while ( !finished && ( millis -= 50 ) > 0 ) {
TimeUnit.MILLISECONDS.sleep( 50 );
}
} catch ( InterruptedException ex1 ) {
Thread.currentThread( ).interrupt( );
}
}
public static Boolean isFinished( ) {
return finished;
}
public static Boolean isShuttingDown( ) {
return shutdown;
}
/**
* Prepares the system to execute the bootstrap sequence defined by {@link Bootstrap.Stage}.
*
* The initialization phase needs to identify all {@link Bootstrapper} implementations available
* locally -- this determines what components it is possible to 'bootstrap' on the current host.
* Subsequently, component configuration is prepared and bootstrapper dependency contraints are
* evaluated. The bootstrappers which conform to the state of the local system are associated with
* their respective {@link EmpyreanService.State}.
*
* The following steps are performed in order.
*
* <ol>
* <li><b>Component configurations</b>: Load the component configuration files from the local jar
* files. This determines which services it is possible to start in the <tt>local</tt> context.</li>
*
* <li><b>Print configurations</b>: The configuration is printed for review.</li>
*
* <li><b>Discovery ({@link ServiceJarDiscovery}</b>: First, find all instantiable descendants of
* {@code ServiceJarDiscovery}. Second, execute each discovery implementation. <b>NOTE:</b> This
* step finds the available bootstrappers but does not evaluate their dependency constraints.</li>
*
* <li><b>Print configurations</b>: The configuration is printed for review.</li>
* <li><b>Print configurations</b>: The configuration is printed for review.</li>
* </ol>
*
* @see Component#startService(com.eucalyptus.component.ServiceConfiguration)
* @see ServiceJarDiscovery
* @see Bootstrap#loadConfigs
* @see Bootstrap#doDiscovery()
*
* @throws Exception
*/
public static void init( ) throws Exception {
Runtime.getRuntime( ).addShutdownHook( new Thread( "bootstrap-shutdown-hook" ) {
@Override
public void run( ) {
LOG.info( "Marked shutdown" );
Bootstrap.shutdown = Boolean.TRUE;
}
} );
/**
* Populate the binding cache. Skip it when running the upgrade.
*/
LOG.info( LogUtil.header( "Populating binding cache." ) );
BindingCache.compileBindings( );
/**
* run discovery to find (primarily) bootstrappers, msg typs, bindings, util-providers, etc. See
* the descendants of {@link ServiceJarDiscovery}.
*
* @see ServiceJarDiscovery
*/
LOG.info( LogUtil.header( "Initializing discoverable bootstrap resources." ) );
Bootstrap.doDiscovery( );
LOG.info( LogUtil.header( "Initializing component identifiers:" ) );
for ( ComponentId compId : ComponentIds.list( ) ) {
Components.create( compId );
}
/**
* Create the component stubs (but do not startService) to do dependency checks on bootstrappers
* and satisfy any forward references from bootstrappers.
*/
LOG.info( LogUtil.header( "Building core local services: cloudLocal=" + BootstrapArgs.isCloudController( ) ) );
for ( Component comp : Components.whichCanLoad( ) ) {
try {
comp.initService( );
} catch ( Exception ex ) {
LOG.error( ex, ex );
}
}
LOG.info( LogUtil.header( "Initializing component resources:" ) );
Bootstrap.applyTransition( Component.State.INITIALIZED, Components.whichCanLoad( ) );
LOG.info( LogUtil.header( "Initializing bootstrappers." ) );
Bootstrap.initBootstrappers( );
LOG.info( LogUtil.header( "System ready: starting bootstrap." ) );
for ( Component c : Components.list( ) ) {
LOG.info( c.toString( ) );
}
}
static void applyTransition( Component.State state, Iterable<Component> components ) {
applyTransition( state, Iterables.toArray( components, Component.class ) );
}
private static void applyTransition( final Component.State state, Component... components ) {
ThreadPool exec = Threads.lookup( Empyrean.class );
for ( final Component component : components ) {
ServiceConfiguration config = component.getLocalServiceConfiguration( );
try {
Topology.transition( state ).apply( config ).get( );
} catch ( Exception ex ) {
Exceptions.maybeInterrupted( ex );
if ( !Exceptions.isCausedBy( ex, OrderlyTransitionException.class ) ) {
LOG.error( ex );
}
Logs.extreme( ).error( ex, ex );
}
}
}
public static void initializeSystem( ) throws Exception {
Groovyness.run( "initialize_cloud.groovy" );
}
}