1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.kernel.config;
19
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.LinkedHashSet;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.geronimo.gbean.AbstractName;
27 import org.apache.geronimo.gbean.AbstractNameQuery;
28 import org.apache.geronimo.gbean.GBeanData;
29 import org.apache.geronimo.gbean.GBeanInfo;
30 import org.apache.geronimo.gbean.GBeanInfoBuilder;
31 import org.apache.geronimo.gbean.GBeanLifecycle;
32 import org.apache.geronimo.gbean.InvalidConfigurationException;
33 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
34 import org.apache.geronimo.kernel.GBeanNotFoundException;
35 import org.apache.geronimo.kernel.InternalKernelException;
36 import org.apache.geronimo.kernel.Kernel;
37 import org.apache.geronimo.kernel.management.State;
38 import org.apache.geronimo.kernel.repository.Artifact;
39 import org.apache.geronimo.kernel.repository.ArtifactManager;
40 import org.apache.geronimo.kernel.repository.ArtifactResolver;
41 import org.apache.geronimo.kernel.repository.DefaultArtifactResolver;
42 import org.apache.geronimo.kernel.repository.Repository;
43
44 /**
45 * The standard non-editable ConfigurationManager implementation. That is,
46 * you can save a lost configurations and stuff, but not change the set of
47 * GBeans included in a configuration.
48 *
49 * @version $Rev:386276 $ $Date: 2006-05-26 15:39:58 -0700 (Fri, 26 May 2006) $
50 * @see EditableConfigurationManager
51 */
52 public class KernelConfigurationManager extends SimpleConfigurationManager implements GBeanLifecycle {
53
54 protected final Kernel kernel;
55 protected final ManageableAttributeStore attributeStore;
56 protected final PersistentConfigurationList configurationList;
57 private final ArtifactManager artifactManager;
58 protected final ClassLoader classLoader;
59 private final ShutdownHook shutdownHook;
60 private boolean online = true;
61
62 public KernelConfigurationManager(Kernel kernel,
63 Collection stores,
64 ManageableAttributeStore attributeStore,
65 PersistentConfigurationList configurationList,
66 ArtifactManager artifactManager,
67 ArtifactResolver artifactResolver,
68 Collection repositories,
69 Collection watchers,
70 ClassLoader classLoader) {
71
72 super(stores,
73 createArtifactResolver(artifactResolver, artifactManager, repositories),
74 repositories, watchers);
75
76 this.kernel = kernel;
77 this.attributeStore = attributeStore;
78 this.configurationList = configurationList;
79 this.artifactManager = artifactManager;
80 this.classLoader = classLoader;
81
82 shutdownHook = new ShutdownHook(kernel);
83 }
84
85 private static ArtifactResolver createArtifactResolver(ArtifactResolver artifactResolver, ArtifactManager artifactManager, Collection repositories) {
86 if (artifactResolver != null) {
87 return artifactResolver;
88 }
89 return new DefaultArtifactResolver(artifactManager, repositories, null);
90 }
91
92 public synchronized LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
93
94 AbstractName abstractName = null;
95 try {
96 abstractName = Configuration.getConfigurationAbstractName(configurationId);
97 } catch (InvalidConfigException e) {
98 throw new RuntimeException(e);
99 }
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
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
139 gbeanData.setAttribute("managedAttributeStore", attributeStore);
140
141
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
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
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
167 configuration = (Configuration) kernel.getGBean(configurationName);
168
169
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
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
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
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
264 try {
265 kernel.stopGBean(configurationName);
266 } catch (GBeanNotFoundException ignored) {
267
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
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
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
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 }