
org.apache.geronimo.kernel.config.KernelConfigurationManager Maven / Gradle / Ivy
The newest version!
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.geronimo.kernel.config;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.gbean.AbstractNameQuery;
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.gbean.InvalidConfigurationException;
import org.apache.geronimo.gbean.annotation.GBean;
import org.apache.geronimo.gbean.annotation.OsgiService;
import org.apache.geronimo.gbean.annotation.ParamReference;
import org.apache.geronimo.gbean.annotation.ParamSpecial;
import org.apache.geronimo.gbean.annotation.SpecialAttributeType;
import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
import org.apache.geronimo.kernel.GBeanNotFoundException;
import org.apache.geronimo.kernel.InternalKernelException;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.kernel.management.State;
import org.apache.geronimo.kernel.repository.Artifact;
import org.apache.geronimo.kernel.repository.ArtifactManager;
import org.apache.geronimo.kernel.repository.ArtifactResolver;
import org.apache.geronimo.kernel.repository.DefaultArtifactResolver;
import org.apache.geronimo.kernel.repository.ListableRepository;
import org.apache.geronimo.kernel.repository.MissingDependencyException;
import org.apache.geronimo.kernel.util.CircularReferencesException;
import org.apache.geronimo.kernel.util.IllegalNodeConfigException;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The standard non-editable ConfigurationManager implementation. That is,
* you can save a lost configurations and stuff, but not change the set of
* GBeans included in a configuration.
*
* @version $Rev:386276 $ $Date: 2011-12-14 02:00:08 +0800 (Wed, 14 Dec 2011) $
*/
@GBean(j2eeType = "ConfigurationManager")
@OsgiService
public class KernelConfigurationManager extends SimpleConfigurationManager implements GBeanLifecycle {
protected final Kernel kernel;
protected final ManageableAttributeStore attributeStore;
protected final PersistentConfigurationList configurationList;
private final ArtifactManager artifactManager;
private final ShutdownHook shutdownHook;
private boolean online = true;
public KernelConfigurationManager(@ParamSpecial(type = SpecialAttributeType.kernel) Kernel kernel,
@ParamReference(name = "Stores", namingType = "ConfigurationStore") Collection stores,
@ParamReference(name = "AttributeStore", namingType = "AttributeStore") ManageableAttributeStore attributeStore,
@ParamReference(name = "PersistentConfigurationList") PersistentConfigurationList configurationList,
@ParamReference(name = "ArtifactManager", namingType = "ArtifactManager") ArtifactManager artifactManager,
@ParamReference(name = "ArtifactResolver", namingType = "ArtifactResolver") ArtifactResolver artifactResolver,
@ParamReference(name = "Repositories", namingType = "Repository") Collection repositories,
@ParamReference(name = "Watchers") Collection watchers,
@ParamSpecial(type = SpecialAttributeType.bundleContext) BundleContext bundleContext) {
super(stores,
createArtifactResolver(artifactResolver, artifactManager, repositories),
repositories, watchers, bundleContext);
this.kernel = kernel;
this.attributeStore = attributeStore;
this.configurationList = configurationList;
this.artifactManager = artifactManager;
shutdownHook = new ShutdownHook(kernel, configurationModel);
}
private static ArtifactResolver createArtifactResolver(ArtifactResolver artifactResolver, ArtifactManager artifactManager, Collection repositories) {
if (artifactResolver != null) {
return artifactResolver;
}
//TODO no reference to this may cause problems
return new DefaultArtifactResolver(artifactManager, repositories, null, Collections.emptyList());
}
public synchronized LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
// todo hack for bootstrap deploy
AbstractName abstractName = null;
try {
abstractName = Configuration.getConfigurationAbstractName(configurationId);
} catch (InvalidConfigException e) {
throw new RuntimeException(e);
}
if (getConfiguration(configurationId) == null && kernel.isLoaded(abstractName)) {
try {
Configuration configuration = (Configuration) kernel.getGBean(abstractName);
addNewConfigurationToModel(configuration);
configurationModel.load(configurationId);
configurationModel.start(configurationId);
return new LifecycleResults();
} catch (GBeanNotFoundException e) {
// configuration was unloaded, just continue as normal
}
}
return super.loadConfiguration(configurationId);
}
protected void load(Artifact configurationId) throws NoSuchConfigException {
super.load(configurationId);
if (configurationList != null) {
configurationList.addConfiguration(configurationId);
}
}
protected void migrateConfiguration(Artifact oldName, Artifact newName, Configuration configuration, boolean running) throws NoSuchConfigException {
super.migrateConfiguration(oldName, newName, configuration, running);
if (configurationList != null) {
configurationList.migrateConfiguration(oldName, newName, configuration);
if (running) {
configurationList.startConfiguration(newName);
}
}
}
protected Configuration load(ConfigurationData configurationData, LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException {
Artifact configurationId = configurationData.getId();
AbstractName configurationName = Configuration.getConfigurationAbstractName(configurationId);
GBeanData gbeanData = new GBeanData(configurationName, Configuration.class);
gbeanData.setAttribute("configurationData", configurationData);
DependencyNode dependencyNode = null;
ConfigurationResolver configurationResolver = new ConfigurationResolver(configurationData, repositories, getArtifactResolver());
gbeanData.setAttribute("configurationResolver", configurationResolver);
try {
dependencyNode = buildDependencyNode(configurationData);
gbeanData.setAttribute("dependencyNode", dependencyNode);
// gbeanData.setAttribute("classLoaderHolder", classLoaderHolder);
gbeanData.setAttribute("allServiceParents", buildAllServiceParents(loadedConfigurations, dependencyNode));
} catch (MissingDependencyException e) {
throw new InvalidConfigException(e);
// } catch (MalformedURLException e) {
// throw new InvalidConfigException(e);
// } catch (NoSuchConfigException e) {
// throw new InvalidConfigException(e);
}
gbeanData.setAttribute("configurationManager", this);
//TODO is this dangerous? should really add dependency on attribute store name
gbeanData.setAttribute("attributeStore", attributeStore);
// add parents to the parents reference collection
LinkedHashSet parentNames = new LinkedHashSet();
for (Artifact resolvedParentId : resolvedParentIds) {
if (isConfiguration(resolvedParentId)) {
AbstractName parentName = Configuration.getConfigurationAbstractName(resolvedParentId);
parentNames.add(parentName);
}
}
gbeanData.addDependencies(parentNames);
// load the configuration
try {
//TODO OSGI more likely use the configuration bundle??
kernel.loadGBean(gbeanData, bundleContext);
} catch (GBeanAlreadyExistsException e) {
throw new InvalidConfigException("Unable to load configuration gbean " + configurationId, e);
}
// start the configuration and assure it started
Configuration configuration;
try {
kernel.startGBean(configurationName);
if (State.RUNNING_INDEX != kernel.getGBeanState(configurationName)) {
String stateReason = kernel.getStateReason(configurationName);
throw new InvalidConfigurationException("Configuration gbean failed to start " + configurationId + "\nreason: " + stateReason);
}
// get the configuration
configuration = (Configuration) kernel.getGBean(configurationName);
// declare the dependencies as loaded
if (artifactManager != null) {
artifactManager.loadArtifacts(configurationId, configuration.getDependencyNode().getParents());
}
Map moreLoadedConfigurations = new LinkedHashMap(loadedConfigurations);
moreLoadedConfigurations.put(dependencyNode.getId(), configuration);
for (Map.Entry childEntry : configurationData.getChildConfigurations().entrySet()) {
ConfigurationResolver childResolver = configurationResolver.createChildResolver(childEntry.getKey());
Configuration child = doLoad(childEntry.getValue(), resolvedParentIds, moreLoadedConfigurations, childResolver);
configuration.addChild(child);
}
log.debug("Loaded Configuration {}", configurationName);
} catch (Exception e) {
unload(configurationId);
if (e instanceof InvalidConfigException) {
throw (InvalidConfigException) e;
}
throw new InvalidConfigException("Error starting configuration gbean " + configurationId, e);
}
return configuration;
}
public void start(Configuration configuration) throws InvalidConfigException {
if (online) {
ConfigurationUtil.startConfigurationGBeans(configuration.getAbstractName(), configuration, kernel);
}
if (configurationList != null && configuration.getConfigurationData().isAutoStart()) {
configurationList.startConfiguration(configuration.getId());
}
}
public boolean isOnline() {
return online;
}
public void setOnline(boolean online) {
this.online = online;
}
protected void stop(Configuration configuration) {
stopRecursive(configuration);
if (configurationList != null) {
configurationList.stopConfiguration(configuration.getId());
}
}
private void stopRecursive(Configuration configuration) {
// stop all of the child configurations first
for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) {
Configuration childConfiguration = (Configuration) iterator.next();
stopRecursive(childConfiguration);
}
Collection gbeans;
try {
List sortedGBeans = ConfigurationUtil.sortGBeanDataByDependency(configuration.getGBeans().values());
Collections.reverse(sortedGBeans);
gbeans = sortedGBeans;
} catch (IllegalNodeConfigException e) {
gbeans = configuration.getGBeans().values();
} catch (CircularReferencesException e) {
gbeans = configuration.getGBeans().values();
}
// stop the gbeans
for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) {
GBeanData gbeanData = iterator.next();
AbstractName gbeanName = gbeanData.getAbstractName();
try {
kernel.stopGBean(gbeanName);
} catch (GBeanNotFoundException ignored) {
} catch (IllegalStateException ignored) {
} catch (InternalKernelException kernelException) {
log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException);
}
}
// unload the gbeans
for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) {
GBeanData gbeanData = iterator.next();
AbstractName gbeanName = gbeanData.getAbstractName();
try {
kernel.unloadGBean(gbeanName);
} catch (GBeanNotFoundException ignored) {
} catch (IllegalStateException ignored) {
} catch (InternalKernelException kernelException) {
log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException);
}
}
}
protected void unload(Configuration configuration) {
Artifact configurationId = configuration.getId();
unload(configurationId);
}
private void unload(Artifact configurationId) {
AbstractName configurationName;
try {
configurationName = Configuration.getConfigurationAbstractName(configurationId);
} catch (InvalidConfigException e) {
throw new AssertionError(e);
}
if (artifactManager != null) {
artifactManager.unloadAllArtifacts(configurationId);
}
// unload this configuration
try {
kernel.stopGBean(configurationName);
} catch (GBeanNotFoundException ignored) {
// Good
} catch (Exception stopException) {
log.warn("Unable to stop failed configuration: " + configurationId, stopException);
}
try {
kernel.unloadGBean(configurationName);
} catch (GBeanNotFoundException ignored) {
// Good
} catch (Exception unloadException) {
log.warn("Unable to unload failed configuration: " + configurationId, unloadException);
}
}
protected void uninstall(Artifact configurationId) {
if (configurationList != null) {
configurationList.removeConfiguration(configurationId);
}
}
public void doStart() {
kernel.registerShutdownHook(shutdownHook);
}
public void doStop() {
kernel.unregisterShutdownHook(shutdownHook);
}
public void doFail() {
log.error("Cofiguration manager failed");
}
private static class ShutdownHook implements Runnable {
private final Kernel kernel;
private final ConfigurationModel configurationModel;
private final Logger log = LoggerFactory.getLogger(ShutdownHook.class);
public ShutdownHook(Kernel kernel, ConfigurationModel configurationModel) {
this.kernel = kernel;
this.configurationModel = configurationModel;
}
public void run() {
while (true) {
Set configs = kernel.listGBeans(new AbstractNameQuery(Configuration.class.getName()));
if (configs.isEmpty()) {
return;
}
LinkedHashSet orderedConfigs = new LinkedHashSet();
for (Iterator i = configs.iterator(); i.hasNext();) {
AbstractName configName = (AbstractName) i.next();
if (kernel.isLoaded(configName) && !orderedConfigs.contains(configName)) {
LinkedHashSet startedChildren = configurationModel.getStartedChildren(configName.getArtifact());
for (Iterator iterator = startedChildren.iterator(); iterator.hasNext();) {
Artifact configurationId = (Artifact) iterator.next();
Set childConfig = kernel.listGBeans(new AbstractNameQuery(configurationId, Collections.emptyMap(), Configuration.class.getName()));
if (!childConfig.isEmpty()) {
AbstractName childConfigName = (AbstractName) childConfig.iterator().next();
if (!orderedConfigs.contains(childConfigName))
orderedConfigs.add(childConfigName);
}
}
orderedConfigs.add(configName);
}
}
for (Iterator i = orderedConfigs.iterator(); i.hasNext();) {
AbstractName configName = (AbstractName) i.next();
try {
kernel.stopGBean(configName);
} catch (GBeanNotFoundException e) {
// ignore
} catch (InternalKernelException e) {
log.warn("Could not stop configuration: " + configName, e);
}
try {
kernel.unloadGBean(configName);
} catch (GBeanNotFoundException e) {
// ignore
}
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy