001 /** 002 * 003 * Copyright 2003-2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.kernel.config; 019 020 import java.util.Collection; 021 import java.util.Iterator; 022 import java.util.LinkedHashSet; 023 import java.util.Map; 024 import java.util.Set; 025 026 import org.apache.geronimo.gbean.AbstractName; 027 import org.apache.geronimo.gbean.AbstractNameQuery; 028 import org.apache.geronimo.gbean.GBeanData; 029 import org.apache.geronimo.gbean.GBeanInfo; 030 import org.apache.geronimo.gbean.GBeanInfoBuilder; 031 import org.apache.geronimo.gbean.GBeanLifecycle; 032 import org.apache.geronimo.gbean.InvalidConfigurationException; 033 import org.apache.geronimo.kernel.GBeanAlreadyExistsException; 034 import org.apache.geronimo.kernel.GBeanNotFoundException; 035 import org.apache.geronimo.kernel.InternalKernelException; 036 import org.apache.geronimo.kernel.Kernel; 037 import org.apache.geronimo.kernel.management.State; 038 import org.apache.geronimo.kernel.repository.Artifact; 039 import org.apache.geronimo.kernel.repository.ArtifactManager; 040 import org.apache.geronimo.kernel.repository.ArtifactResolver; 041 import org.apache.geronimo.kernel.repository.DefaultArtifactResolver; 042 import org.apache.geronimo.kernel.repository.Repository; 043 044 /** 045 * The standard non-editable ConfigurationManager implementation. That is, 046 * you can save a lost configurations and stuff, but not change the set of 047 * GBeans included in a configuration. 048 * 049 * @version $Rev:386276 $ $Date: 2006-05-26 15:39:58 -0700 (Fri, 26 May 2006) $ 050 * @see EditableConfigurationManager 051 */ 052 public class KernelConfigurationManager extends SimpleConfigurationManager implements GBeanLifecycle { 053 054 protected final Kernel kernel; 055 protected final ManageableAttributeStore attributeStore; 056 protected final PersistentConfigurationList configurationList; 057 private final ArtifactManager artifactManager; 058 protected final ClassLoader classLoader; 059 private final ShutdownHook shutdownHook; 060 private boolean online = true; 061 062 public KernelConfigurationManager(Kernel kernel, 063 Collection stores, 064 ManageableAttributeStore attributeStore, 065 PersistentConfigurationList configurationList, 066 ArtifactManager artifactManager, 067 ArtifactResolver artifactResolver, 068 Collection repositories, 069 Collection watchers, 070 ClassLoader classLoader) { 071 072 super(stores, 073 createArtifactResolver(artifactResolver, artifactManager, repositories), 074 repositories, watchers); 075 076 this.kernel = kernel; 077 this.attributeStore = attributeStore; 078 this.configurationList = configurationList; 079 this.artifactManager = artifactManager; 080 this.classLoader = classLoader; 081 082 shutdownHook = new ShutdownHook(kernel); 083 } 084 085 private static ArtifactResolver createArtifactResolver(ArtifactResolver artifactResolver, ArtifactManager artifactManager, Collection repositories) { 086 if (artifactResolver != null) { 087 return artifactResolver; 088 } 089 return new DefaultArtifactResolver(artifactManager, repositories, null); 090 } 091 092 public synchronized LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException { 093 // todo hack for bootstrap deploy 094 AbstractName abstractName = null; 095 try { 096 abstractName = Configuration.getConfigurationAbstractName(configurationId); 097 } catch (InvalidConfigException e) { 098 throw new RuntimeException(e); 099 } 100 if (getConfiguration(configurationId) == null && kernel.isLoaded(abstractName)) { 101 try { 102 Configuration configuration = (Configuration) kernel.getGBean(abstractName); 103 addNewConfigurationToModel(configuration); 104 configurationModel.load(configurationId); 105 configurationModel.start(configurationId); 106 return new LifecycleResults(); 107 } catch (GBeanNotFoundException e) { 108 // configuration was unloaded, just continue as normal 109 } 110 } 111 112 return super.loadConfiguration(configurationId); 113 } 114 115 protected void load(Artifact configurationId) throws NoSuchConfigException { 116 super.load(configurationId); 117 if (configurationList != null) { 118 configurationList.addConfiguration(configurationId); 119 } 120 } 121 122 protected void migrateConfiguration(Artifact oldName, Artifact newName, Configuration configuration, boolean running) throws NoSuchConfigException { 123 super.migrateConfiguration(oldName, newName, configuration, running); 124 if (configurationList != null) { 125 configurationList.migrateConfiguration(oldName, newName, configuration); 126 if(running) { 127 configurationList.startConfiguration(newName); 128 } 129 } 130 } 131 132 protected Configuration load(ConfigurationData configurationData, LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException { 133 Artifact configurationId = configurationData.getId(); 134 AbstractName configurationName = Configuration.getConfigurationAbstractName(configurationId); 135 GBeanData gbeanData = new GBeanData(configurationName, Configuration.GBEAN_INFO); 136 gbeanData.setAttribute("configurationData", configurationData); 137 gbeanData.setAttribute("configurationResolver", new ConfigurationResolver(configurationData, repositories, getArtifactResolver())); 138 //TODO is this dangerous? 139 gbeanData.setAttribute("managedAttributeStore", attributeStore); 140 141 // add parents to the parents reference collection 142 LinkedHashSet parentNames = new LinkedHashSet(); 143 for (Iterator iterator = resolvedParentIds.iterator(); iterator.hasNext();) { 144 Artifact resolvedParentId = (Artifact) iterator.next(); 145 AbstractName parentName = Configuration.getConfigurationAbstractName(resolvedParentId); 146 parentNames.add(parentName); 147 } 148 gbeanData.addDependencies(parentNames); 149 gbeanData.setReferencePatterns("Parents", parentNames); 150 151 // load the configuration 152 try { 153 kernel.loadGBean(gbeanData, classLoader); 154 } catch (GBeanAlreadyExistsException e) { 155 throw new InvalidConfigException("Unable to load configuration gbean " + configurationId, e); 156 } 157 158 // start the configuration and assure it started 159 Configuration configuration; 160 try { 161 kernel.startGBean(configurationName); 162 if (State.RUNNING_INDEX != kernel.getGBeanState(configurationName)) { 163 throw new InvalidConfigurationException("Configuration gbean failed to start " + configurationId); 164 } 165 166 // get the configuration 167 configuration = (Configuration) kernel.getGBean(configurationName); 168 169 // declare the dependencies as loaded 170 if (artifactManager != null) { 171 artifactManager.loadArtifacts(configurationId, configuration.getDependencies()); 172 } 173 174 log.debug("Loaded Configuration " + configurationName); 175 } catch (Exception e) { 176 unload(configurationId); 177 if (e instanceof InvalidConfigException) { 178 throw (InvalidConfigException) e; 179 } 180 throw new InvalidConfigException("Error starting configuration gbean " + configurationId, e); 181 } 182 return configuration; 183 } 184 185 public void start(Configuration configuration) throws InvalidConfigException { 186 if (online) { 187 ConfigurationUtil.startConfigurationGBeans(configuration.getAbstractName(), configuration, kernel); 188 } 189 190 if (configurationList != null && configuration.getConfigurationData().isAutoStart()) { 191 configurationList.startConfiguration(configuration.getId()); 192 } 193 } 194 195 public boolean isOnline() { 196 return online; 197 } 198 199 public void setOnline(boolean online) { 200 this.online = online; 201 } 202 203 protected void stop(Configuration configuration) { 204 stopRecursive(configuration); 205 if (configurationList != null) { 206 configurationList.stopConfiguration(configuration.getId()); 207 } 208 } 209 210 private void stopRecursive(Configuration configuration) { 211 // stop all of the child configurations first 212 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) { 213 Configuration childConfiguration = (Configuration) iterator.next(); 214 stopRecursive(childConfiguration); 215 } 216 217 Collection gbeans = configuration.getGBeans().values(); 218 219 // stop the gbeans 220 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { 221 GBeanData gbeanData = (GBeanData) iterator.next(); 222 AbstractName gbeanName = gbeanData.getAbstractName(); 223 try { 224 kernel.stopGBean(gbeanName); 225 } catch (GBeanNotFoundException ignored) { 226 } catch (IllegalStateException ignored) { 227 } catch (InternalKernelException kernelException) { 228 log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException); 229 } 230 } 231 232 // unload the gbeans 233 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { 234 GBeanData gbeanData = (GBeanData) iterator.next(); 235 AbstractName gbeanName = gbeanData.getAbstractName(); 236 try { 237 kernel.unloadGBean(gbeanName); 238 } catch (GBeanNotFoundException ignored) { 239 } catch (IllegalStateException ignored) { 240 } catch (InternalKernelException kernelException) { 241 log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException); 242 } 243 } 244 } 245 246 protected void unload(Configuration configuration) { 247 Artifact configurationId = configuration.getId(); 248 unload(configurationId); 249 } 250 251 private void unload(Artifact configurationId) { 252 AbstractName configurationName; 253 try { 254 configurationName = Configuration.getConfigurationAbstractName(configurationId); 255 } catch (InvalidConfigException e) { 256 throw new AssertionError(e); 257 } 258 259 if (artifactManager != null) { 260 artifactManager.unloadAllArtifacts(configurationId); 261 } 262 263 // unload this configuration 264 try { 265 kernel.stopGBean(configurationName); 266 } catch (GBeanNotFoundException ignored) { 267 // Good 268 } catch (Exception stopException) { 269 log.warn("Unable to stop failed configuration: " + configurationId, stopException); 270 } 271 272 try { 273 kernel.unloadGBean(configurationName); 274 } catch (GBeanNotFoundException ignored) { 275 // Good 276 } catch (Exception unloadException) { 277 log.warn("Unable to unload failed configuration: " + configurationId, unloadException); 278 } 279 } 280 281 public void doStart() { 282 kernel.registerShutdownHook(shutdownHook); 283 } 284 285 public void doStop() { 286 kernel.unregisterShutdownHook(shutdownHook); 287 } 288 289 public void doFail() { 290 log.error("Cofiguration manager failed"); 291 } 292 293 private static class ShutdownHook implements Runnable { 294 private final Kernel kernel; 295 296 public ShutdownHook(Kernel kernel) { 297 this.kernel = kernel; 298 } 299 300 public void run() { 301 while (true) { 302 Set configs = kernel.listGBeans(new AbstractNameQuery(Configuration.class.getName())); 303 if (configs.isEmpty()) { 304 return; 305 } 306 for (Iterator i = configs.iterator(); i.hasNext();) { 307 AbstractName configName = (AbstractName) i.next(); 308 if (kernel.isLoaded(configName)) { 309 try { 310 kernel.stopGBean(configName); 311 } catch (GBeanNotFoundException e) { 312 // ignore 313 } catch (InternalKernelException e) { 314 log.warn("Could not stop configuration: " + configName, e); 315 } 316 try { 317 kernel.unloadGBean(configName); 318 } catch (GBeanNotFoundException e) { 319 // ignore 320 } 321 } 322 } 323 } 324 } 325 } 326 327 public static final GBeanInfo GBEAN_INFO; 328 329 static { 330 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(KernelConfigurationManager.class, "ConfigurationManager"); 331 infoFactory.addAttribute("kernel", Kernel.class, false); 332 infoFactory.addReference("Stores", ConfigurationStore.class, "ConfigurationStore"); 333 infoFactory.addReference("AttributeStore", ManageableAttributeStore.class, ManageableAttributeStore.ATTRIBUTE_STORE); 334 infoFactory.addReference("PersistentConfigurationList", PersistentConfigurationList.class, PersistentConfigurationList.PERSISTENT_CONFIGURATION_LIST); 335 infoFactory.addReference("ArtifactManager", ArtifactManager.class, "ArtifactManager"); 336 infoFactory.addReference("ArtifactResolver", ArtifactResolver.class, "ArtifactResolver"); 337 infoFactory.addReference("Repositories", Repository.class, "Repository"); 338 infoFactory.addReference("Watchers", DeploymentWatcher.class); 339 infoFactory.addAttribute("classLoader", ClassLoader.class, false); 340 infoFactory.addInterface(ConfigurationManager.class); 341 infoFactory.setConstructor(new String[]{"kernel", "Stores", "AttributeStore", "PersistentConfigurationList", "ArtifactManager", "ArtifactResolver", "Repositories", "Watchers", "classLoader"}); 342 GBEAN_INFO = infoFactory.getBeanInfo(); 343 } 344 345 public static GBeanInfo getGBeanInfo() { 346 return GBEAN_INFO; 347 } 348 }