
com.netflix.governator.lifecycle.LifecycleManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of governator Show documentation
Show all versions of governator Show documentation
governator developed by Netflix
/*
* Copyright 2012 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.governator.lifecycle;
import java.beans.Introspector;
import java.io.Closeable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.naming.NamingException;
import javax.validation.ConstraintViolation;
import javax.validation.Path;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.netflix.governator.annotations.PreConfiguration;
import com.netflix.governator.annotations.WarmUp;
import com.netflix.governator.configuration.ConfigurationColumnWriter;
import com.netflix.governator.configuration.ConfigurationDocumentation;
import com.netflix.governator.configuration.ConfigurationMapper;
import com.netflix.governator.configuration.ConfigurationProvider;
/**
* Main instance management container
*/
@Singleton
public class LifecycleManager implements Closeable
{
private final Logger log = LoggerFactory.getLogger(getClass());
private final Map objectStates = Maps.newConcurrentMap();
private final List preDestroys = new CopyOnWriteArrayList();
private final AtomicReference state = new AtomicReference(State.LATENT);
private final ConfigurationDocumentation configurationDocumentation;
private final ConfigurationProvider configurationProvider;
private final ConfigurationMapper configurationMapper;
private final Collection listeners;
private final Collection resourceLocators;
private final ValidatorFactory factory;
private final Injector injector;
private com.netflix.governator.LifecycleManager newLifecycleManager;
public LifecycleManager()
{
this(new LifecycleManagerArguments(), null);
}
public LifecycleManager(LifecycleManagerArguments arguments)
{
this(arguments, null);
}
@Inject
public LifecycleManager(LifecycleManagerArguments arguments, Injector injector)
{
this.injector = injector;
configurationMapper = arguments.getConfigurationMapper();
newLifecycleManager = arguments.getLifecycleManager();
listeners = ImmutableSet.copyOf(arguments.getLifecycleListeners());
resourceLocators = ImmutableSet.copyOf(arguments.getResourceLocators());
factory = Validation.buildDefaultValidatorFactory();
configurationDocumentation = arguments.getConfigurationDocumentation();
configurationProvider = arguments.getConfigurationProvider();
}
/**
* Return the lifecycle listener if any
*
* @return listener or null
*/
public Collection getListeners()
{
return listeners;
}
/**
* Add the objects to the container. Their assets will be loaded, post construct methods called, etc.
*
* @param objects objects to add
* @throws Exception errors
*/
public void add(Object... objects) throws Exception
{
for ( Object obj : objects )
{
add(obj);
}
}
/**
* Add the object to the container. Its assets will be loaded, post construct methods called, etc.
*
* @param obj object to add
* @throws Exception errors
*/
public void add(Object obj) throws Exception
{
add(obj, new LifecycleMethods(obj.getClass()));
}
/**
* Add the object to the container. Its assets will be loaded, post construct methods called, etc.
* This version helps performance when the lifecycle methods have already been calculated
*
* @param obj object to add
* @param methods calculated lifecycle methods
* @throws Exception errors
*/
public void add(Object obj, LifecycleMethods methods) throws Exception
{
Preconditions.checkState(state.get() != State.CLOSED, "LifecycleManager is closed");
startInstance(obj, methods);
if ( hasStarted() )
{
initializeObjectPostStart(obj);
}
}
/**
* Returns true if the lifecycle has started (i.e. {@link #start()} has been called).
*
* @return true/false
*/
public boolean hasStarted()
{
return state.get() == State.STARTED;
}
/**
* Return the current state of the given object or LATENT if unknown
*
* @param obj object to check
* @return state
*/
public LifecycleState getState(Object obj)
{
LifecycleState lifecycleState = objectStates.get(new StateKey(obj));
if ( lifecycleState == null )
{
lifecycleState = hasStarted() ? LifecycleState.ACTIVE : LifecycleState.LATENT;
}
return lifecycleState;
}
/**
* The manager MUST be started. Note: this method
* waits indefinitely for warm up methods to complete
*
* @throws Exception errors
*/
public void start() throws Exception
{
start(0, null);
}
/**
* The manager MUST be started. This version of start() has a maximum
* wait period for warm up methods.
*
* @param maxWait maximum wait time for warm up methods - if the time elapses, the warm up methods are interrupted
* @param unit time unit
* @return true if warm up methods successfully executed, false if the time elapses
* @throws Exception errors
*/
@Deprecated
public boolean start(long maxWait, TimeUnit unit) throws Exception
{
Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTING), "Already started");
validate();
new ConfigurationColumnWriter(configurationDocumentation).output(log);
if (newLifecycleManager != null) {
newLifecycleManager.notifyStarted();
}
state.set(State.STARTED);
return true;
}
@Override
public synchronized void close()
{
if ( state.compareAndSet(State.STARTING, State.CLOSED) || state.compareAndSet(State.STARTED, State.CLOSED) )
{
try
{
if (newLifecycleManager != null) {
newLifecycleManager.notifyShutdown();
}
stopInstances();
}
catch ( Exception e )
{
log.error("While stopping instances", e);
}
finally
{
preDestroys.clear();
objectStates.clear();
}
}
}
/**
* Run the validations on the managed objects. This is done automatically when {@link #start()} is called.
* But you can call this at any time you need.
*
* @throws ValidationException
*/
public void validate() throws ValidationException
{
ValidationException exception = null;
Validator validator = factory.getValidator();
for ( StateKey key : objectStates.keySet() )
{
Object obj = key.obj;
exception = internalValidateObject(exception, obj, validator);
}
if ( exception != null )
{
throw exception;
}
}
/**
* Run validations on the given object
*
* @param obj the object to validate
* @throws ValidationException
*/
public void validate(Object obj) throws ValidationException
{
Validator validator = factory.getValidator();
ValidationException exception = internalValidateObject(null, obj, validator);
if ( exception != null )
{
throw exception;
}
}
private void setState(Object obj, LifecycleState state)
{
objectStates.put(new StateKey(obj), state);
for ( LifecycleListener listener : listeners )
{
listener.stateChanged(obj, state);
}
}
private ValidationException internalValidateObject(ValidationException exception, Object obj, Validator validator)
{
Set> violations = validator.validate(obj);
for ( ConstraintViolation
© 2015 - 2025 Weber Informatics LLC | Privacy Policy