View Javadoc

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          // todo hack for bootstrap deploy
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                 // 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 }