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