in framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/SimpleConfigurationManager.java [1136:1528]
private LifecycleResults reloadConfiguration(UnloadedConfiguration existingUnloadedConfiguration, ConfigurationData newConfigurationData, LifecycleMonitor monitor) throws LifecycleException, NoSuchConfigException {
boolean force = false;
Artifact existingConfigurationId = existingUnloadedConfiguration.getConfigurationData().getId();
Artifact newConfigurationId = newConfigurationData.getId();
//
// recursively load the new configuration; this will catch any new parents
//
LinkedHashMap<Artifact, UnloadedConfiguration> newConfigurations = new LinkedHashMap<Artifact, UnloadedConfiguration>();
try {
loadDepthFirst(newConfigurationData, newConfigurations, monitor);
} catch (Exception e) {
monitor.finished();
throw new LifecycleException("reload", newConfigurationId, e);
}
//
// get a list of the started configuration, so we can restart them later
//
Set<Artifact> started = configurationModel.getStarted();
//
// get a list of the child configurations that will need to reload
//
// note: we are iterating in reverse order
LinkedHashMap<Artifact, LinkedHashSet<Artifact>> existingParents = new LinkedHashMap<Artifact, LinkedHashSet<Artifact>>();
LinkedHashMap<Artifact, UnloadedConfiguration> reloadChildren = new LinkedHashMap<Artifact, UnloadedConfiguration>();
for (Artifact configurationId : reverse(configurationModel.reload(existingConfigurationId))) {
if (configurationId.equals(existingConfigurationId)) {
continue;
}
// if new configurations contains the child something we have a circular dependency
if (newConfigurations.containsKey(configurationId)) {
throw new LifecycleException("reload", newConfigurationId,
new IllegalStateException("Circular depenency between " + newConfigurationId + " and " + configurationId));
}
Configuration configuration = getConfiguration(configurationId);
ConfigurationData configurationData = configuration.getConfigurationData();
// save off the exising resolved parent ids in case we need to restore this configuration
LinkedHashSet<Artifact> existingParentIds = getResolvedParentIds(configuration);
existingParents.put(configurationId, existingParentIds);
// check that the child doen't have a hard dependency on the old configuration
LinkedHashSet<Artifact> resolvedParentIds;
if (hasHardDependency(existingConfigurationId, configurationData)) {
if (force) {
throw new LifecycleException("reload", newConfigurationId,
new IllegalStateException("Existing configuration " + configurationId + " has a hard dependency on the current version of this configuration " + existingConfigurationId));
}
// we leave the resolved parent ids null to signal that we should not reload the configuration
resolvedParentIds = null;
} else {
resolvedParentIds = new LinkedHashSet<Artifact>(existingParentIds);
resolvedParentIds.remove(existingConfigurationId);
resolvedParentIds.add(newConfigurationId);
}
reloadChildren.put(configurationId, new UnloadedConfiguration(configurationData, resolvedParentIds));
monitor.addConfiguration(configurationId);
}
//
// unload the children
//
// note: we are iterating in reverse order
LifecycleResults results = new LifecycleResults();
for (Artifact configurationId : reverse(reloadChildren).keySet()) {
Configuration configuration = getConfiguration(configurationId);
// first make sure it is stopped
if (started.contains(configurationId)) {
monitor.stopping(configurationId);
stop(configuration);
monitor.succeeded(configurationId);
results.addStopped(configurationId);
} else {
// call stop just to be sure the beans aren't running
stop(configuration);
}
// now unload it
monitor.unloading(configurationId);
unload(configuration);
monitor.succeeded(configurationId);
results.addUnloaded(configurationId);
}
//
// unload the existing config
//
Configuration existingConfiguration = getConfiguration(existingConfigurationId);
if (started.contains(existingConfigurationId)) {
monitor.stopping(existingConfigurationId);
stop(existingConfiguration);
monitor.succeeded(existingConfigurationId);
results.addStopped(existingConfigurationId);
} else if (existingConfiguration != null) {
// call stop just to be sure the beans aren't running
stop(existingConfiguration);
}
if (existingConfiguration != null) {
monitor.unloading(existingConfigurationId);
unload(existingConfiguration);
monitor.succeeded(existingConfigurationId);
results.addUnloaded(existingConfigurationId);
}
//
// load the new configurations
//
boolean reinstatedExisting = false;
/* reduce variable scope */
{
Map<Artifact, Configuration> loadedParents = new LinkedHashMap<Artifact, Configuration>();
Map<Artifact, Configuration> startedParents = new LinkedHashMap<Artifact, Configuration>();
Configuration newConfiguration = null;
Artifact configurationId = null;
try {
//
// load all of the new configurations
//
for (Map.Entry<Artifact, UnloadedConfiguration> entry : newConfigurations.entrySet()) {
configurationId = entry.getKey();
UnloadedConfiguration unloadedConfiguration = entry.getValue();
monitor.loading(configurationId);
Configuration configuration = load(unloadedConfiguration.getConfigurationData(), unloadedConfiguration.getResolvedParentIds(), loadedParents);
monitor.succeeded(configurationId);
if (configurationId.equals(newConfigurationId)) {
newConfiguration = configuration;
synchronized (reloadingConfigurationLock) {
reloadingConfiguration = configuration;
}
} else {
loadedParents.put(configurationId, configuration);
}
}
if (newConfiguration == null) {
AssertionError cause = new AssertionError("Internal error: configuration was not load");
results.addFailed(newConfigurationId, cause);
throw new LifecycleException("reload", newConfigurationId, results);
}
//
// start the new configurations if the old one was running
//
if (started.contains(existingConfigurationId)) {
// determine which of the parents we need to start
LinkedHashSet<Configuration> startList = new LinkedHashSet<Configuration>();
for (Configuration serviceParent : getStartParents(newConfiguration)) {
if (loadedParents.containsKey(serviceParent.getId())) {
startList.add(serviceParent);
}
}
// start the new parents
for (Configuration startParent : startList) {
monitor.starting(configurationId);
start(startParent);
monitor.succeeded(configurationId);
startedParents.put(configurationId, startParent);
}
// start the new configuration
monitor.starting(newConfigurationId);
start(newConfiguration);
monitor.succeeded(newConfigurationId);
}
//
// update the results
//
results.setLoaded(loadedParents.keySet());
results.addLoaded(newConfigurationId);
if (started.contains(existingConfigurationId)) {
results.setStarted(startedParents.keySet());
results.addStarted(newConfigurationId);
}
//
// update the model
//
// add all of the new configurations the model
//TODO OSGI TOTALLY BROKEN
// addNewConfigurationsToModel(loadedParents);
// now ugrade the existing node in the model
if (configurationModel.containsConfiguration(existingConfigurationId)) {
configurationModel.upgradeConfiguration(existingConfigurationId,
newConfigurationId,
getConfigurationIds(getLoadParents(newConfiguration)),
getConfigurationIds(getStartParents(newConfiguration)));
} else {
configurationModel.addConfiguration(newConfigurationId,
getConfigurationIds(getLoadParents(newConfiguration)),
getConfigurationIds(getStartParents(newConfiguration)));
load(newConfigurationId);
}
// replace the configuraiton in he configurations map
configurations.remove(existingConfiguration.getId());
configurations.put(newConfigurationId, newConfiguration);
// migrate the configuration settings
migrateConfiguration(existingConfigurationId, newConfigurationId, newConfiguration, started.contains(existingConfigurationId));
} catch (Exception e) {
monitor.failed(configurationId, e);
results.addFailed(configurationId, e);
//
// stop and unload all configurations that were actually loaded
//
for (Configuration configuration : startedParents.values()) {
stop(configuration);
}
for (Configuration configuration : loadedParents.values()) {
unload(configuration);
}
// stop and unload the newConfiguration
if (newConfiguration != null) {
stop(newConfiguration);
unload(newConfiguration);
}
//
// atempt to reinstate the old configuation
//
Configuration configuration = null;
try {
configuration = load(existingUnloadedConfiguration.getConfigurationData(),
existingUnloadedConfiguration.getResolvedParentIds(),
Collections.<Artifact, Configuration>emptyMap()
);
synchronized (reloadingConfigurationLock) {
reloadingConfiguration = configuration;
}
// if the configuration was started before restart it
if (started.contains(existingConfigurationId)) {
start(configuration);
results.addStarted(existingConfigurationId);
}
// don't mark as loded until start completes as it may thorw an exception
results.addLoaded(existingConfigurationId);
configurations.put(existingConfigurationId, configuration);
reinstatedExisting = true;
} catch (Exception ignored) {
monitor.failed(existingConfigurationId, e);
// we tried our best
if (configuration != null) {
unload(configuration);
}
//
// cleanup the model
//
for (Artifact childId : results.getUnloaded()) {
configurationModel.unload(childId);
removeConfigurationFromModel(childId);
}
throw new LifecycleException("reload", newConfigurationId, results);
}
} finally {
synchronized (reloadingConfigurationLock) {
reloadingConfiguration = null;
}
}
}
//
// reload as many child configurations as possible
//
Set<Artifact> skip = new HashSet<Artifact>();
for (Map.Entry<Artifact, UnloadedConfiguration> entry : reloadChildren.entrySet()) {
Artifact configurationId = entry.getKey();
UnloadedConfiguration unloadedConfiguration = entry.getValue();
// skip the configurations that have alredy failed or are children of failed configurations
if (skip.contains(configurationId)) {
continue;
}
// try to load the configuation
Configuration configuration = null;
try {
// get the correct resolved parent ids based on if we are loading with the new config id or the existing one
LinkedHashSet<Artifact> resolvedParentIds;
if (!reinstatedExisting) {
resolvedParentIds = unloadedConfiguration.getResolvedParentIds();
} else {
resolvedParentIds = existingParents.get(configurationId);
}
// if the resolved parent ids is null, then we are not supposed to reload this configuration
if (resolvedParentIds != null) {
monitor.loading(configurationId);
configuration = load(unloadedConfiguration.getConfigurationData(),
resolvedParentIds,
Collections.<Artifact,
Configuration>emptyMap()
);
synchronized (reloadingConfigurationLock) {
reloadingConfiguration = configuration;
}
monitor.succeeded(configurationId);
// if the configuration was started before restart it
if (started.contains(configurationId)) {
monitor.starting(configurationId);
start(configuration);
monitor.succeeded(configurationId);
results.addStarted(configurationId);
}
// don't mark as loded until start completes as it may thow an exception
results.addLoaded(configurationId);
configurations.put(configurationId, configuration);
} else {
removeConfigurationFromModel(configurationId);
}
} catch (Exception e) {
// the configuraiton failed to restart
results.addFailed(configurationId, e);
monitor.failed(configurationId, e);
skip.add(configurationId);
// unload the configuration if it was loaded and failed in start
if (configuration != null) {
unload(configuration);
}
// officially unload the configuration in the model (without gc)
LinkedHashSet<Artifact> unloadList = configurationModel.unload(configurationId, false);
configurationModel.removeConfiguration(configurationId);
// all of the configurations to be unloaded must be in our unloaded list, or the model is corrupt
if (!reloadChildren.keySet().containsAll(unloadList)) {
throw new AssertionError("Configuration data model is corrupt. You must restart your server.");
}
// add the children of the failed configuration to the results as unloaded
for (Artifact failedId : unloadList) {
// if any of the failed configuration are in the reloaded set, the model is
// corrupt because we loaded a child before a parent
if (results.wasLoaded(failedId)) {
throw new AssertionError("Configuration data model is corrupt. You must restart your server.");
}
skip.add(failedId);
}
} finally {
synchronized (reloadingConfigurationLock) {
reloadingConfiguration = null;
}
}
}
//
// If nothing failed, delete all the unloaded modules that weren't reloaded
//
if (!results.wasLoaded(existingConfigurationId) && !results.wasFailed(existingConfigurationId)) {
try {
uninstallConfiguration(existingConfigurationId);
} catch (IOException e) {
log.error("Unable to uninstall configuration " + existingConfigurationId, e);
}
}
monitor.finished();
if (results.wasFailed(newConfigurationId) || !results.wasLoaded(newConfigurationId)) {
throw new LifecycleException("restart", newConfigurationId, results);
}
return results;
}