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 */ 017 package org.apache.geronimo.kernel.config; 018 019 import java.io.IOException; 020 import java.util.ArrayList; 021 import java.util.Collection; 022 import java.util.Collections; 023 import java.util.HashSet; 024 import java.util.Iterator; 025 import java.util.LinkedHashMap; 026 import java.util.LinkedHashSet; 027 import java.util.List; 028 import java.util.ListIterator; 029 import java.util.Map; 030 import java.util.Set; 031 032 import org.apache.commons.logging.Log; 033 import org.apache.commons.logging.LogFactory; 034 import org.apache.geronimo.gbean.AbstractName; 035 import org.apache.geronimo.gbean.GBeanInfo; 036 import org.apache.geronimo.gbean.GBeanInfoBuilder; 037 import org.apache.geronimo.kernel.management.State; 038 import org.apache.geronimo.kernel.repository.Artifact; 039 import org.apache.geronimo.kernel.repository.ArtifactResolver; 040 import org.apache.geronimo.kernel.repository.Dependency; 041 import org.apache.geronimo.kernel.repository.Environment; 042 import org.apache.geronimo.kernel.repository.ImportType; 043 import org.apache.geronimo.kernel.repository.MissingDependencyException; 044 import org.apache.geronimo.kernel.repository.Repository; 045 import org.apache.geronimo.kernel.repository.Version; 046 047 /** 048 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 049 */ 050 public class SimpleConfigurationManager implements ConfigurationManager { 051 protected static final Log log = LogFactory.getLog(SimpleConfigurationManager.class); 052 protected final Collection stores; 053 private final ArtifactResolver artifactResolver; 054 protected final Map configurations = new LinkedHashMap(); 055 protected final ConfigurationModel configurationModel = new ConfigurationModel(); 056 protected final Collection<? extends Repository> repositories; 057 protected final Collection watchers; 058 059 /** 060 * When this is not null, it points to the "new" configuration that is 061 * part of an in-process reload operation. This configuration will 062 * definitely be loaded, but might not be started yet. It shold never be 063 * populated outside the scope of a reload operation. 064 */ 065 private Configuration reloadingConfiguration; 066 067 068 public SimpleConfigurationManager(Collection stores, ArtifactResolver artifactResolver, Collection<? extends Repository> repositories) { 069 this(stores, artifactResolver, repositories, Collections.EMPTY_SET); 070 } 071 072 public SimpleConfigurationManager(Collection stores, 073 ArtifactResolver artifactResolver, 074 Collection<? extends Repository> repositories, 075 Collection watchers) { 076 if (stores == null) stores = Collections.EMPTY_SET; 077 if (repositories == null) repositories = Collections.emptySet(); 078 if (watchers == null) watchers = Collections.EMPTY_SET; 079 080 this.stores = stores; 081 this.artifactResolver = artifactResolver; 082 this.repositories = repositories; 083 this.watchers = watchers; 084 } 085 086 public synchronized boolean isInstalled(Artifact configId) { 087 if (!configId.isResolved()) { 088 throw new IllegalArgumentException("Artifact " + configId + " is not fully resolved"); 089 } 090 List storeSnapshot = getStoreList(); 091 for (int i = 0; i < storeSnapshot.size(); i++) { 092 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 093 if (store.containsConfiguration(configId)) { 094 return true; 095 } 096 } 097 return false; 098 } 099 100 public synchronized boolean isLoaded(Artifact configId) { 101 if (!configId.isResolved()) { 102 throw new IllegalArgumentException("Artifact " + configId + " is not fully resolved"); 103 } 104 if (reloadingConfiguration != null && reloadingConfiguration.getId().equals(configId)) { 105 return true; 106 } 107 return configurationModel.isLoaded(configId); 108 } 109 110 public synchronized boolean isRunning(Artifact configId) { 111 if (!configId.isResolved()) { 112 throw new IllegalArgumentException("Artifact " + configId + " is not fully resolved"); 113 } 114 return configurationModel.isStarted(configId); 115 } 116 117 public Artifact[] getInstalled(Artifact query) { 118 Artifact[] all = artifactResolver.queryArtifacts(query); 119 List configs = new ArrayList(); 120 for (int i = 0; i < all.length; i++) { 121 Artifact artifact = all[i]; 122 if (isConfiguration(artifact)) { 123 configs.add(artifact); 124 } 125 } 126 if (configs.size() == all.length) { 127 return all; 128 } 129 return (Artifact[]) configs.toArray(new Artifact[configs.size()]); 130 } 131 132 public Artifact[] getLoaded(Artifact query) { 133 return configurationModel.getLoaded(query); 134 } 135 136 public Artifact[] getRunning(Artifact query) { 137 return configurationModel.getStarted(query); 138 } 139 140 141 public List listStores() { 142 List storeSnapshot = getStoreList(); 143 List result = new ArrayList(storeSnapshot.size()); 144 for (int i = 0; i < storeSnapshot.size(); i++) { 145 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 146 result.add(store.getAbstractName()); 147 } 148 return result; 149 } 150 151 public ConfigurationStore[] getStores() { 152 List storeSnapshot = getStoreList(); 153 return (ConfigurationStore[]) storeSnapshot.toArray(new ConfigurationStore[storeSnapshot.size()]); 154 } 155 156 public Collection<? extends Repository> getRepositories() { 157 return repositories; 158 } 159 160 public List listConfigurations() { 161 List storeSnapshot = getStoreList(); 162 List list = new ArrayList(); 163 for (int i = 0; i < storeSnapshot.size(); i++) { 164 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 165 list.addAll(listConfigurations(store)); 166 } 167 return list; 168 } 169 170 public ConfigurationStore getStoreForConfiguration(Artifact configId) { 171 if (!configId.isResolved()) { 172 throw new IllegalArgumentException("Artifact " + configId + " is not fully resolved"); 173 } 174 List storeSnapshot = getStoreList(); 175 for (int i = 0; i < storeSnapshot.size(); i++) { 176 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 177 if (store.containsConfiguration(configId)) { 178 return store; 179 } 180 } 181 return null; 182 } 183 184 public List<ConfigurationInfo> listConfigurations(AbstractName storeName) throws NoSuchStoreException { 185 List<ConfigurationStore> storeSnapshot = getStoreList(); 186 for (ConfigurationStore store : storeSnapshot) { 187 if (storeName.equals(store.getAbstractName())) { 188 return listConfigurations(store); 189 } 190 } 191 throw new NoSuchStoreException("No such store: " + storeName); 192 } 193 194 private List<ConfigurationInfo> listConfigurations(ConfigurationStore store) { 195 List<ConfigurationInfo> list = store.listConfigurations(); 196 for (ListIterator<ConfigurationInfo> iterator = list.listIterator(); iterator.hasNext();) { 197 ConfigurationInfo configurationInfo = (ConfigurationInfo) iterator.next(); 198 if (isRunning(configurationInfo.getConfigID())) { 199 configurationInfo = new ConfigurationInfo(store.getAbstractName(), 200 configurationInfo.getConfigID(), 201 configurationInfo.getType(), 202 configurationInfo.getCreated(), 203 configurationInfo.getOwnedConfigurations(), 204 configurationInfo.getChildConfigurations(), 205 configurationInfo.getInPlaceLocation(), 206 State.RUNNING); 207 } else { 208 configurationInfo = new ConfigurationInfo(store.getAbstractName(), 209 configurationInfo.getConfigID(), 210 configurationInfo.getType(), 211 configurationInfo.getCreated(), 212 configurationInfo.getOwnedConfigurations(), 213 configurationInfo.getChildConfigurations(), 214 configurationInfo.getInPlaceLocation(), 215 State.STOPPED); 216 } 217 iterator.set(configurationInfo); 218 } 219 return list; 220 } 221 222 public boolean isConfiguration(Artifact artifact) { 223 if (!artifact.isResolved()) { 224 throw new IllegalArgumentException("Artifact " + artifact + " is not fully resolved"); 225 } 226 synchronized (this) { 227 // if it is loaded, it is definitely a configuration 228 if (configurations.containsKey(artifact)) { 229 return true; 230 } 231 } 232 233 // see if any stores think it is a configuration 234 List storeSnapshot = getStoreList(); 235 for (int i = 0; i < storeSnapshot.size(); i++) { 236 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 237 if (store.containsConfiguration(artifact)) { 238 return true; 239 } 240 } 241 return false; 242 } 243 244 public synchronized Configuration getConfiguration(Artifact configurationId) { 245 if (!configurationId.isResolved()) { 246 throw new IllegalArgumentException("Artifact " + configurationId + " is not fully resolved"); 247 } 248 if (reloadingConfiguration != null && reloadingConfiguration.getId().equals(configurationId)) { 249 return reloadingConfiguration; 250 } 251 return (Configuration) configurations.get(configurationId); 252 } 253 254 public synchronized LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException { 255 return loadConfiguration(configurationId, NullLifecycleMonitor.INSTANCE); 256 } 257 258 public synchronized LifecycleResults loadConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException { 259 if (!configurationId.isResolved()) { 260 throw new IllegalArgumentException("Artifact " + configurationId + " is not fully resolved"); 261 } 262 if (isLoaded(configurationId)) { 263 // already loaded, so just mark the configuration as user loaded 264 load(configurationId); 265 266 monitor.finished(); 267 return new LifecycleResults(); 268 } 269 270 // load the ConfigurationData for the new configuration 271 ConfigurationData configurationData = null; 272 try { 273 configurationData = loadConfigurationData(configurationId, monitor); 274 } catch (Exception e) { 275 monitor.finished(); 276 throw new LifecycleException("load", configurationId, e); 277 } 278 279 // load the configuration 280 LifecycleResults results = loadConfiguration(configurationData, monitor); 281 282 return results; 283 } 284 285 public synchronized LifecycleResults loadConfiguration(ConfigurationData configurationData) throws NoSuchConfigException, LifecycleException { 286 return loadConfiguration(configurationData, NullLifecycleMonitor.INSTANCE); 287 } 288 289 public synchronized LifecycleResults loadConfiguration(ConfigurationData configurationData, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException { 290 Artifact id = configurationData.getId(); 291 LifecycleResults results = new LifecycleResults(); 292 if (!isLoaded(id)) { 293 // recursively load configurations from the new child to the parents 294 LinkedHashMap configurationsToLoad = new LinkedHashMap(); 295 try { 296 loadDepthFirst(configurationData, configurationsToLoad, monitor); 297 } catch (Exception e) { 298 monitor.finished(); 299 throw new LifecycleException("load", id, e); 300 } 301 302 // load and start the unloaded the gbean for each configuration (depth first) 303 Map actuallyLoaded = new LinkedHashMap(configurationsToLoad.size()); 304 Artifact configurationId = null; 305 try { 306 for (Iterator iterator = configurationsToLoad.entrySet().iterator(); iterator.hasNext();) { 307 Map.Entry entry = (Map.Entry) iterator.next(); 308 configurationId = (Artifact) entry.getKey(); 309 UnloadedConfiguration unloadedConfiguration = (UnloadedConfiguration) entry.getValue(); 310 311 monitor.loading(configurationId); 312 Configuration configuration = load(unloadedConfiguration.getConfigurationData(), unloadedConfiguration.getResolvedParentIds(), actuallyLoaded); 313 monitor.succeeded(configurationId); 314 315 actuallyLoaded.put(configurationId, configuration); 316 } 317 } catch (Exception e) { 318 monitor.failed(configurationId, e); 319 320 // there was a problem, so we need to unload all configurations that were actually loaded 321 for (Iterator iterator = actuallyLoaded.values().iterator(); iterator.hasNext();) { 322 Configuration configuration = (Configuration) iterator.next(); 323 unload(configuration); 324 } 325 326 monitor.finished(); 327 throw new LifecycleException("load", id, e); 328 } 329 330 // update the status of the loaded configurations 331 addNewConfigurationsToModel(actuallyLoaded); 332 results.setLoaded(actuallyLoaded.keySet()); 333 } 334 load(id); 335 monitor.finished(); 336 return results; 337 } 338 339 protected void load(Artifact configurationId) throws NoSuchConfigException { 340 configurationModel.load(configurationId); 341 } 342 343 protected Configuration load(ConfigurationData configurationData, LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException { 344 Artifact configurationId = configurationData.getId(); 345 try { 346 Collection parents = findParentConfigurations(resolvedParentIds, loadedConfigurations); 347 348 Configuration configuration = new Configuration(parents, configurationData, new ConfigurationResolver(configurationData, repositories, artifactResolver), null); 349 configuration.doStart(); 350 return configuration; 351 } catch (Exception e) { 352 throw new InvalidConfigException("Error starting configuration gbean " + configurationId, e); 353 } 354 } 355 356 private Collection findParentConfigurations(LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException { 357 LinkedHashMap parents = new LinkedHashMap(); 358 for (Iterator iterator = resolvedParentIds.iterator(); iterator.hasNext();) { 359 Artifact resolvedArtifact = (Artifact) iterator.next(); 360 361 Configuration parent = null; 362 if (loadedConfigurations.containsKey(resolvedArtifact)) { 363 parent = (Configuration) loadedConfigurations.get(resolvedArtifact); 364 } else if (isLoaded(resolvedArtifact)) { 365 parent = getConfiguration(resolvedArtifact); 366 } else { 367 throw new InvalidConfigException("Cound not find parent configuration: " + resolvedArtifact); 368 } 369 370 parents.put(resolvedArtifact, parent); 371 } 372 return parents.values(); 373 } 374 375 private void addNewConfigurationsToModel(Map loadedConfigurations) throws NoSuchConfigException { 376 for (Iterator iterator = loadedConfigurations.values().iterator(); iterator.hasNext();) { 377 Configuration configuration = (Configuration) iterator.next(); 378 addNewConfigurationToModel(configuration); 379 } 380 } 381 382 protected void addNewConfigurationToModel(Configuration configuration) throws NoSuchConfigException { 383 configurationModel.addConfiguation(configuration.getId(), 384 getConfigurationIds(getLoadParents(configuration)), 385 getConfigurationIds(getStartParents(configuration))); 386 configurations.put(configuration.getId(), configuration); 387 } 388 389 protected LinkedHashSet getLoadParents(Configuration configuration) { 390 LinkedHashSet loadParent = new LinkedHashSet(configuration.getClassParents()); 391 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) { 392 Configuration childConfiguration = (Configuration) iterator.next(); 393 LinkedHashSet childLoadParent = getLoadParents(childConfiguration); 394 395 // remove this configuration from the parent Ids since it will cause an infinite loop 396 childLoadParent.remove(configuration); 397 398 loadParent.addAll(childLoadParent); 399 } 400 return loadParent; 401 } 402 403 protected LinkedHashSet getStartParents(Configuration configuration) { 404 LinkedHashSet startParent = new LinkedHashSet(configuration.getServiceParents()); 405 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) { 406 Configuration childConfiguration = (Configuration) iterator.next(); 407 LinkedHashSet childStartParent = getStartParents(childConfiguration); 408 409 // remove this configuration from the parent Ids since it will cause an infinite loop 410 childStartParent.remove(configuration); 411 412 startParent.addAll(childStartParent); 413 } 414 return startParent; 415 } 416 417 private static LinkedHashSet<Artifact> getConfigurationIds(Collection<Configuration> configurations) { 418 LinkedHashSet<Artifact> configurationIds = new LinkedHashSet<Artifact>(configurations.size()); 419 for (Configuration configuration : configurations) { 420 configurationIds.add(configuration.getId()); 421 } 422 return configurationIds; 423 } 424 425 private synchronized void loadDepthFirst(ConfigurationData configurationData, LinkedHashMap<Artifact, UnloadedConfiguration> configurationsToLoad, LifecycleMonitor monitor) throws NoSuchConfigException, IOException, InvalidConfigException, MissingDependencyException { 426 // if this parent hasn't already been processed, iterate into the parent 427 Artifact configurationId = configurationData.getId(); 428 if (!configurationsToLoad.containsKey(configurationId)) { 429 monitor.resolving(configurationId); 430 LinkedHashSet<Artifact> resolvedParentIds = resolveParentIds(configurationData); 431 monitor.succeeded(configurationId); 432 433 for (Artifact parentId : resolvedParentIds) { 434 // if this parent id hasn't already been loaded and is actually a configuration 435 if (!isLoaded(parentId) && isConfiguration(parentId)) { 436 ConfigurationData parentConfigurationData = loadConfigurationData(parentId, monitor); 437 loadDepthFirst(parentConfigurationData, configurationsToLoad, monitor); 438 } 439 } 440 441 // depth first - all unloaded parents have been added, now add this configuration 442 configurationsToLoad.put(configurationId, new UnloadedConfiguration(configurationData, resolvedParentIds)); 443 } 444 } 445 446 // Return ids that can be loaded in sorted order. Remove loadable ids from source set. 447 public LinkedHashSet<Artifact> sort(List<Artifact> ids, LifecycleMonitor monitor) throws InvalidConfigException, IOException, NoSuchConfigException, MissingDependencyException { 448 LinkedHashSet<Artifact> sorted = new LinkedHashSet<Artifact>(); 449 sort(ids, sorted, monitor); 450 sorted.retainAll(ids); 451 ids.removeAll(sorted); 452 return sorted; 453 } 454 455 private void sort(Collection<Artifact> ids, LinkedHashSet<Artifact> sorted, LifecycleMonitor monitor) throws InvalidConfigException, IOException, NoSuchConfigException, MissingDependencyException { 456 for (Artifact id : ids) { 457 if (!sorted.contains(id)) { 458 try { 459 //configuration may not be loadable yet, the config-store may not be available to load from 460 ConfigurationData data = loadConfigurationData(id, monitor); 461 LinkedHashSet<Artifact> parents = resolveParentIds(data); 462 sort(parents, sorted, monitor); 463 sorted.add(id); 464 } catch (NoSuchConfigException e) { 465 //ignore 466 } catch (IOException e) { 467 //ignore 468 } catch (InvalidConfigException e) { 469 //ignore 470 } catch (MissingDependencyException e) { 471 //ignore 472 } 473 } 474 } 475 } 476 477 private ConfigurationData loadConfigurationData(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, IOException, InvalidConfigException { 478 List<ConfigurationStore> storeSnapshot = getStoreList(); 479 480 monitor.addConfiguration(configurationId); 481 monitor.reading(configurationId); 482 for (ConfigurationStore store : storeSnapshot) { 483 if (store.containsConfiguration(configurationId)) { 484 ConfigurationData configurationData = store.loadConfiguration(configurationId); 485 monitor.succeeded(configurationId); 486 return configurationData; 487 } 488 } 489 NoSuchConfigException exception = new NoSuchConfigException(configurationId); 490 monitor.failed(configurationId, exception); 491 throw exception; 492 } 493 494 private LinkedHashSet<Artifact> resolveParentIds(ConfigurationData configurationData) throws MissingDependencyException, InvalidConfigException { 495 Environment environment = configurationData.getEnvironment(); 496 497 LinkedHashSet<Artifact> parentIds = new LinkedHashSet<Artifact>(); 498 List<Dependency> dependencies = new ArrayList<Dependency>(environment.getDependencies()); 499 for (ListIterator<Dependency> iterator = dependencies.listIterator(); iterator.hasNext();) { 500 Dependency dependency = iterator.next(); 501 Artifact resolvedArtifact = artifactResolver.resolveInClassLoader(dependency.getArtifact()); 502 if (isConfiguration(resolvedArtifact)) { 503 parentIds.add(resolvedArtifact); 504 505 // update the dependency list to contain the resolved artifact 506 dependency = new Dependency(resolvedArtifact, dependency.getImportType()); 507 iterator.set(dependency); 508 } else if (dependency.getImportType() == ImportType.SERVICES) { 509 // Service depdendencies require that the depdencency be a configuration 510 throw new InvalidConfigException("Dependency does not have services: " + resolvedArtifact); 511 } 512 } 513 514 for (Iterator iterator = configurationData.getChildConfigurations().values().iterator(); iterator.hasNext();) { 515 ConfigurationData childConfigurationData = (ConfigurationData) iterator.next(); 516 LinkedHashSet<Artifact> childParentIds = resolveParentIds(childConfigurationData); 517 // remove this configuration's id from the parent Ids since it will cause an infinite loop 518 childParentIds.remove(configurationData.getId()); 519 parentIds.addAll(childParentIds); 520 } 521 return parentIds; 522 } 523 524 private static class UnloadedConfiguration { 525 private final ConfigurationData configurationData; 526 private final LinkedHashSet resolvedParentIds; 527 528 public UnloadedConfiguration(ConfigurationData configurationData, LinkedHashSet resolvedParentIds) { 529 this.configurationData = configurationData; 530 this.resolvedParentIds = resolvedParentIds; 531 } 532 533 public ConfigurationData getConfigurationData() { 534 return configurationData; 535 } 536 537 public LinkedHashSet getResolvedParentIds() { 538 return resolvedParentIds; 539 } 540 } 541 542 public synchronized LifecycleResults startConfiguration(Artifact id) throws NoSuchConfigException, LifecycleException { 543 return startConfiguration(id, NullLifecycleMonitor.INSTANCE); 544 } 545 546 public synchronized LifecycleResults startConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException { 547 if (!id.isResolved()) { 548 throw new IllegalArgumentException("Artifact " + id + " is not fully resolved"); 549 } 550 LinkedHashSet unstartedConfigurations = configurationModel.start(id); 551 552 addConfigurationsToMonitor(monitor, unstartedConfigurations); 553 554 LifecycleResults results = new LifecycleResults(); 555 Artifact configurationId = null; 556 try { 557 for (Iterator iterator = unstartedConfigurations.iterator(); iterator.hasNext();) { 558 configurationId = (Artifact) iterator.next(); 559 Configuration configuration = getConfiguration(configurationId); 560 561 monitor.starting(configurationId); 562 start(configuration); 563 monitor.succeeded(configurationId); 564 565 results.addStarted(configurationId); 566 } 567 } catch (Exception e) { 568 monitor.failed(configurationId, e); 569 configurationModel.stop(id); 570 571 for (Iterator iterator = results.getStarted().iterator(); iterator.hasNext();) { 572 configurationId = (Artifact) iterator.next(); 573 Configuration configuration = getConfiguration(configurationId); 574 monitor.stopping(configurationId); 575 stop(configuration); 576 monitor.succeeded(configurationId); 577 } 578 monitor.finished(); 579 throw new LifecycleException("start", id, e); 580 } 581 monitor.finished(); 582 return results; 583 } 584 585 protected void start(Configuration configuration) throws Exception { 586 throw new UnsupportedOperationException(); 587 } 588 589 public synchronized LifecycleResults stopConfiguration(Artifact id) throws NoSuchConfigException { 590 return stopConfiguration(id, NullLifecycleMonitor.INSTANCE); 591 } 592 593 public synchronized LifecycleResults stopConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException { 594 if (!id.isResolved()) { 595 throw new IllegalArgumentException("Artifact " + id + " is not fully resolved"); 596 } 597 LinkedHashSet stopList = configurationModel.stop(id); 598 599 addConfigurationsToMonitor(monitor, stopList); 600 601 LifecycleResults results = new LifecycleResults(); 602 for (Iterator iterator = stopList.iterator(); iterator.hasNext();) { 603 Artifact configurationId = (Artifact) iterator.next(); 604 Configuration configuration = getConfiguration(configurationId); 605 606 monitor.stopping(configurationId); 607 stop(configuration); 608 monitor.succeeded(configurationId); 609 610 results.addStopped(configurationId); 611 } 612 613 monitor.finished(); 614 return results; 615 } 616 617 protected void stop(Configuration configuration) { 618 // Don't throw an exception because we call this from unload to be sure that all 619 // unloaded configurations are stopped first 620 } 621 622 public synchronized LifecycleResults restartConfiguration(Artifact id) throws NoSuchConfigException, LifecycleException { 623 return restartConfiguration(id, NullLifecycleMonitor.INSTANCE); 624 } 625 626 public synchronized LifecycleResults restartConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException { 627 if (!id.isResolved()) { 628 throw new IllegalArgumentException("Artifact " + id + " is not fully resolved"); 629 } 630 // get a sorted list of configurations to restart 631 LinkedHashSet restartList = configurationModel.restart(id); 632 633 addConfigurationsToMonitor(monitor, restartList); 634 635 // stop the configuations 636 LifecycleResults results = new LifecycleResults(); 637 for (Iterator iterator = restartList.iterator(); iterator.hasNext();) { 638 Artifact configurationId = (Artifact) iterator.next(); 639 Configuration configuration = getConfiguration(configurationId); 640 monitor.stopping(configurationId); 641 stop(configuration); 642 monitor.succeeded(configurationId); 643 results.addStopped(configurationId); 644 } 645 646 // reverse the list 647 restartList = reverse(restartList); 648 649 // restart the configurations 650 Set skip = new HashSet(); 651 for (Iterator iterator = restartList.iterator(); iterator.hasNext();) { 652 Artifact configurationId = (Artifact) iterator.next(); 653 654 // skip the configurations that have alredy failed or are children of failed configurations 655 if (skip.contains(configurationId)) { 656 continue; 657 } 658 659 // try to start the configuation 660 try { 661 Configuration configuration = getConfiguration(configurationId); 662 monitor.starting(configurationId); 663 start(configuration); 664 monitor.succeeded(configurationId); 665 results.addStarted(configurationId); 666 } catch (Exception e) { 667 // the configuraiton failed to restart 668 results.addFailed(configurationId, e); 669 monitor.failed(configurationId, e); 670 skip.add(configurationId); 671 672 // officially stop the configuration in the model (without gc) 673 LinkedHashSet stopList = configurationModel.stop(configurationId, false); 674 675 // all of the configurations to be stopped must be in our restart list, or the model is corrupt 676 if (!restartList.containsAll(stopList)) { 677 throw new AssertionError("Configuration data model is corrupt. You must restart your server."); 678 } 679 680 // add the children of the failed configuration to the results as stopped 681 for (Iterator iterator1 = stopList.iterator(); iterator1.hasNext();) { 682 Artifact failedId = (Artifact) iterator1.next(); 683 684 // if any of the failed configuration is in the restarted set, the model is 685 // corrupt because we started a child before a parent 686 if (results.wasStarted(failedId)) { 687 throw new AssertionError("Configuration data model is corrupt. You must restart your server."); 688 } 689 690 skip.add(failedId); 691 } 692 } 693 } 694 695 monitor.finished(); 696 if (!results.wasStarted(id)) { 697 throw new LifecycleException("restart", id, results); 698 } 699 return results; 700 } 701 702 public synchronized LifecycleResults unloadConfiguration(Artifact id) throws NoSuchConfigException { 703 return unloadConfiguration(id, NullLifecycleMonitor.INSTANCE); 704 } 705 706 public synchronized LifecycleResults unloadConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException { 707 if (!id.isResolved()) { 708 throw new IllegalArgumentException("Artifact " + id + " is not fully resolved"); 709 } 710 Set started = configurationModel.getStarted(); 711 LinkedHashSet unloadList = configurationModel.unload(id); 712 713 addConfigurationsToMonitor(monitor, unloadList); 714 715 LifecycleResults results = new LifecycleResults(); 716 for (Iterator iterator = unloadList.iterator(); iterator.hasNext();) { 717 Artifact configurationId = (Artifact) iterator.next(); 718 Configuration configuration = getConfiguration(configurationId); 719 720 // first make sure it is stopped 721 if (started.contains(configurationId)) { 722 monitor.stopping(configurationId); 723 stop(configuration); 724 monitor.succeeded(configurationId); 725 results.addStopped(configurationId); 726 } else { 727 // call stop just to be sure the beans aren't running 728 stop(configuration); 729 } 730 731 // now unload it 732 monitor.unloading(configurationId); 733 unload(configuration); 734 monitor.succeeded(configurationId); 735 results.addUnloaded(configurationId); 736 737 // clean up the model 738 removeConfigurationFromModel(configurationId); 739 } 740 monitor.finished(); 741 return results; 742 } 743 744 protected void removeConfigurationFromModel(Artifact configurationId) throws NoSuchConfigException { 745 if (configurationModel.containsConfiguration(configurationId)) { 746 configurationModel.removeConfiguration(configurationId); 747 } 748 configurations.remove(configurationId); 749 } 750 751 protected void unload(Configuration configuration) { 752 try { 753 configuration.doStop(); 754 } catch (Exception e) { 755 log.debug("Problem unloading config: " + configuration.getId(), e); 756 } 757 } 758 759 public synchronized LifecycleResults reloadConfiguration(Artifact id) throws NoSuchConfigException, LifecycleException { 760 return reloadConfiguration(id, NullLifecycleMonitor.INSTANCE); 761 } 762 763 public synchronized LifecycleResults reloadConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException { 764 return reloadConfiguration(id, id.getVersion(), monitor); 765 } 766 767 public synchronized LifecycleResults reloadConfiguration(Artifact id, Version version) throws NoSuchConfigException, LifecycleException { 768 return reloadConfiguration(id, version, NullLifecycleMonitor.INSTANCE); 769 } 770 771 public synchronized LifecycleResults reloadConfiguration(Artifact id, Version version, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException { 772 if (!id.isResolved()) { 773 throw new IllegalArgumentException("Artifact " + id + " is not fully resolved"); 774 } 775 Configuration configuration = getConfiguration(id); 776 if (configuration == null) { // The configuration to reload is not currently loaded 777 ConfigurationData data = null; 778 List storeSnapshot = getStoreList(); 779 for (int i = 0; i < storeSnapshot.size(); i++) { 780 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 781 if (store.containsConfiguration(id)) { 782 try { 783 data = store.loadConfiguration(id); 784 } catch (Exception e) { 785 log.warn("Unable to load existing configuration " + id + " from config store", e); 786 } 787 } 788 } 789 if (data == null) { 790 throw new NoSuchConfigException(id); 791 } 792 UnloadedConfiguration existingUnloadedConfiguration = new UnloadedConfiguration(data, new LinkedHashSet()); 793 Artifact newId = new Artifact(id.getGroupId(), id.getArtifactId(), version, id.getType()); 794 ConfigurationData newData = null; 795 try { 796 newData = loadConfigurationData(newId, monitor); 797 } catch (Exception e) { 798 monitor.finished(); 799 throw new LifecycleException("reload", id, e); 800 } 801 802 return reloadConfiguration(existingUnloadedConfiguration, newData, monitor); 803 } else { // The configuration to reload is loaded 804 ConfigurationData existingConfigurationData = configuration.getConfigurationData(); 805 UnloadedConfiguration existingUnloadedConfiguration = new UnloadedConfiguration(existingConfigurationData, getResolvedParentIds(configuration)); 806 807 Artifact newId = new Artifact(id.getGroupId(), id.getArtifactId(), version, id.getType()); 808 809 // reload the ConfigurationData from a store 810 ConfigurationData configurationData = null; 811 try { 812 configurationData = loadConfigurationData(newId, monitor); 813 } catch (Exception e) { 814 monitor.finished(); 815 throw new LifecycleException("reload", id, e); 816 } 817 818 return reloadConfiguration(existingUnloadedConfiguration, configurationData, monitor); 819 } 820 } 821 822 public synchronized LifecycleResults reloadConfiguration(ConfigurationData configurationData) throws LifecycleException, NoSuchConfigException { 823 return reloadConfiguration(configurationData, NullLifecycleMonitor.INSTANCE); 824 } 825 826 public synchronized LifecycleResults reloadConfiguration(ConfigurationData configurationData, LifecycleMonitor monitor) throws LifecycleException, NoSuchConfigException { 827 Configuration configuration = getConfiguration(configurationData.getId()); 828 if (configuration == null) { 829 throw new NoSuchConfigException(configurationData.getId()); 830 } 831 ConfigurationData existingConfigurationData = configuration.getConfigurationData(); 832 UnloadedConfiguration existingUnloadedConfiguration = new UnloadedConfiguration(existingConfigurationData, getResolvedParentIds(configuration)); 833 return reloadConfiguration(existingUnloadedConfiguration, configurationData, monitor); 834 } 835 836 private boolean hasHardDependency(Artifact configurationId, ConfigurationData configurationData) { 837 for (Iterator iterator = configurationData.getEnvironment().getDependencies().iterator(); iterator.hasNext();) { 838 Dependency dependency = (Dependency) iterator.next(); 839 Artifact artifact = dependency.getArtifact(); 840 if (artifact.getVersion() != null && artifact.matches(configurationId)) { 841 return true; 842 } 843 } 844 845 for (Iterator iterator = configurationData.getChildConfigurations().values().iterator(); iterator.hasNext();) { 846 ConfigurationData childConfigurationData = (ConfigurationData) iterator.next(); 847 if (hasHardDependency(configurationId, childConfigurationData)) { 848 return true; 849 } 850 } 851 return false; 852 } 853 854 // todo this method ignores garbage collection of configurations 855 private LifecycleResults reloadConfiguration(UnloadedConfiguration existingUnloadedConfiguration, ConfigurationData newConfigurationData, LifecycleMonitor monitor) throws LifecycleException, NoSuchConfigException { 856 boolean force = false; 857 858 Artifact existingConfigurationId = existingUnloadedConfiguration.getConfigurationData().getId(); 859 Artifact newConfigurationId = newConfigurationData.getId(); 860 861 // 862 // recursively load the new configuration; this will catch any new parents 863 // 864 LinkedHashMap newConfigurations = new LinkedHashMap(); 865 try { 866 loadDepthFirst(newConfigurationData, newConfigurations, monitor); 867 } catch (Exception e) { 868 monitor.finished(); 869 throw new LifecycleException("reload", newConfigurationId, e); 870 } 871 872 // 873 // get a list of the started configuration, so we can restart them later 874 // 875 Set started = configurationModel.getStarted(); 876 877 // 878 // get a list of the child configurations that will need to reload 879 // 880 // note: we are iterating in reverse order 881 LinkedHashMap existingParents = new LinkedHashMap(); 882 LinkedHashMap reloadChildren = new LinkedHashMap(); 883 for (Iterator iterator = reverse(configurationModel.reload(existingConfigurationId)).iterator(); iterator.hasNext();) { 884 Artifact configurationId = (Artifact) iterator.next(); 885 886 if (configurationId.equals(existingConfigurationId)) { 887 continue; 888 } 889 890 // if new configurations contains the child something we have a circular dependency 891 if (newConfigurations.containsKey(configurationId)) { 892 throw new LifecycleException("reload", newConfigurationId, 893 new IllegalStateException("Circular depenency between " + newConfigurationId + " and " + configurationId)); 894 } 895 896 Configuration configuration = getConfiguration(configurationId); 897 ConfigurationData configurationData = configuration.getConfigurationData(); 898 899 // save off the exising resolved parent ids in case we need to restore this configuration 900 LinkedHashSet existingParentIds = getResolvedParentIds(configuration); 901 existingParents.put(configurationId, existingParentIds); 902 903 // check that the child doen't have a hard dependency on the old configuration 904 LinkedHashSet resolvedParentIds = null; 905 if (hasHardDependency(existingConfigurationId, configurationData)) { 906 if (force) { 907 throw new LifecycleException("reload", newConfigurationId, 908 new IllegalStateException("Existing configuration " + configurationId + " has a hard dependency on the current version of this configuration " + existingConfigurationId)); 909 } 910 911 // we leave the resolved parent ids null to signal that we should not reload the configuration 912 resolvedParentIds = null; 913 } else { 914 resolvedParentIds = new LinkedHashSet(existingParentIds); 915 resolvedParentIds.remove(existingConfigurationId); 916 resolvedParentIds.add(newConfigurationId); 917 } 918 919 reloadChildren.put(configurationId, new UnloadedConfiguration(configurationData, resolvedParentIds)); 920 monitor.addConfiguration(configurationId); 921 } 922 923 // 924 // unload the children 925 // 926 927 // note: we are iterating in reverse order 928 LifecycleResults results = new LifecycleResults(); 929 for (Iterator iterator = reverse(reloadChildren).keySet().iterator(); iterator.hasNext();) { 930 Artifact configurationId = (Artifact) iterator.next(); 931 Configuration configuration = getConfiguration(configurationId); 932 933 // first make sure it is stopped 934 if (started.contains(configurationId)) { 935 monitor.stopping(configurationId); 936 stop(configuration); 937 monitor.succeeded(configurationId); 938 results.addStopped(configurationId); 939 } else { 940 // call stop just to be sure the beans aren't running 941 stop(configuration); 942 } 943 944 // now unload it 945 monitor.unloading(configurationId); 946 unload(configuration); 947 monitor.succeeded(configurationId); 948 results.addUnloaded(configurationId); 949 } 950 951 // 952 // unload the existing config 953 // 954 Configuration existingConfiguration = getConfiguration(existingConfigurationId); 955 if (started.contains(existingConfigurationId)) { 956 monitor.stopping(existingConfigurationId); 957 stop(existingConfiguration); 958 monitor.succeeded(existingConfigurationId); 959 results.addStopped(existingConfigurationId); 960 } else if (existingConfiguration != null) { 961 // call stop just to be sure the beans aren't running 962 stop(existingConfiguration); 963 } 964 if (existingConfiguration != null) { 965 monitor.unloading(existingConfigurationId); 966 unload(existingConfiguration); 967 monitor.succeeded(existingConfigurationId); 968 results.addUnloaded(existingConfigurationId); 969 } 970 971 // 972 // load the new configurations 973 // 974 boolean reinstatedExisting = false; 975 /* reduce variable scope */ 976 { 977 Map loadedParents = new LinkedHashMap(); 978 Map startedParents = new LinkedHashMap(); 979 Configuration newConfiguration = null; 980 Artifact configurationId = null; 981 try { 982 // 983 // load all of the new configurations 984 // 985 for (Iterator iterator = newConfigurations.entrySet().iterator(); iterator.hasNext();) { 986 Map.Entry entry = (Map.Entry) iterator.next(); 987 configurationId = (Artifact) entry.getKey(); 988 UnloadedConfiguration unloadedConfiguration = (UnloadedConfiguration) entry.getValue(); 989 990 monitor.loading(configurationId); 991 Configuration configuration = load(unloadedConfiguration.getConfigurationData(), unloadedConfiguration.getResolvedParentIds(), loadedParents); 992 monitor.succeeded(configurationId); 993 994 if (configurationId.equals(newConfigurationId)) { 995 newConfiguration = configuration; 996 reloadingConfiguration = configuration; 997 } else { 998 loadedParents.put(configurationId, configuration); 999 } 1000 } 1001 1002 if (newConfiguration == null) { 1003 AssertionError cause = new AssertionError("Internal error: configuration was not load"); 1004 results.addFailed(newConfigurationId, cause); 1005 throw new LifecycleException("reload", newConfigurationId, results); 1006 } 1007 1008 // 1009 // start the new configurations if the old one was running 1010 // 1011 if (started.contains(existingConfigurationId)) { 1012 1013 // determine which of the parents we need to start 1014 LinkedHashSet startList = new LinkedHashSet(); 1015 for (Iterator iterator = getStartParents(newConfiguration).iterator(); iterator.hasNext();) { 1016 Configuration serviceParent = (Configuration) iterator.next(); 1017 if (loadedParents.containsKey(serviceParent.getId())) { 1018 startList.add(serviceParent); 1019 } 1020 } 1021 1022 // start the new parents 1023 for (Iterator iterator = startList.iterator(); iterator.hasNext();) { 1024 Configuration startParent = (Configuration) iterator.next(); 1025 monitor.starting(configurationId); 1026 start(startParent); 1027 monitor.succeeded(configurationId); 1028 1029 startedParents.put(configurationId, startParent); 1030 } 1031 1032 // start the new configuration 1033 monitor.starting(newConfigurationId); 1034 start(newConfiguration); 1035 monitor.succeeded(newConfigurationId); 1036 } 1037 1038 // 1039 // update the results 1040 // 1041 results.setLoaded(loadedParents.keySet()); 1042 results.addLoaded(newConfigurationId); 1043 if (started.contains(existingConfigurationId)) { 1044 results.setStarted(startedParents.keySet()); 1045 results.addStarted(newConfigurationId); 1046 } 1047 1048 // 1049 // update the model 1050 // 1051 1052 // add all of the new configurations the model 1053 addNewConfigurationsToModel(loadedParents); 1054 1055 // now ugrade the existing node in the model 1056 if (configurationModel.containsConfiguration(existingConfigurationId)) { 1057 configurationModel.upgradeConfiguration(existingConfigurationId, 1058 newConfigurationId, 1059 getConfigurationIds(getLoadParents(newConfiguration)), 1060 getConfigurationIds(getStartParents(newConfiguration))); 1061 } else { 1062 configurationModel.addConfiguation(newConfigurationId, 1063 getConfigurationIds(getLoadParents(newConfiguration)), 1064 getConfigurationIds(getStartParents(newConfiguration))); 1065 load(newConfigurationId); 1066 } 1067 1068 // replace the configuraiton in he configurations map 1069 configurations.remove(existingConfiguration); 1070 configurations.put(newConfigurationId, newConfiguration); 1071 1072 // migrate the configuration settings 1073 migrateConfiguration(existingConfigurationId, newConfigurationId, newConfiguration, started.contains(existingConfigurationId)); 1074 } catch (Exception e) { 1075 monitor.failed(configurationId, e); 1076 results.addFailed(configurationId, e); 1077 1078 // 1079 // stop and unload all configurations that were actually loaded 1080 // 1081 for (Iterator iterator = startedParents.values().iterator(); iterator.hasNext();) { 1082 Configuration configuration = (Configuration) iterator.next(); 1083 stop(configuration); 1084 } 1085 for (Iterator iterator = loadedParents.values().iterator(); iterator.hasNext();) { 1086 Configuration configuration = (Configuration) iterator.next(); 1087 unload(configuration); 1088 } 1089 1090 // stop and unload the newConfiguration 1091 if (newConfiguration != null) { 1092 stop(newConfiguration); 1093 unload(newConfiguration); 1094 } 1095 1096 // 1097 // atempt to reinstate the old configuation 1098 // 1099 Configuration configuration = null; 1100 try { 1101 configuration = load(existingUnloadedConfiguration.getConfigurationData(), 1102 existingUnloadedConfiguration.getResolvedParentIds(), 1103 Collections.EMPTY_MAP); 1104 reloadingConfiguration = configuration; 1105 // if the configuration was started before restart it 1106 if (started.contains(existingConfigurationId)) { 1107 start(configuration); 1108 results.addStarted(existingConfigurationId); 1109 } 1110 1111 // don't mark as loded until start completes as it may thorw an exception 1112 results.addLoaded(existingConfigurationId); 1113 1114 configurations.put(existingConfigurationId, configuration); 1115 1116 reinstatedExisting = true; 1117 } catch (Exception ignored) { 1118 monitor.failed(existingConfigurationId, e); 1119 1120 // we tried our best 1121 if (configuration != null) { 1122 unload(configuration); 1123 } 1124 1125 // 1126 // cleanup the model 1127 // 1128 for (Iterator iterator = results.getUnloaded().iterator(); iterator.hasNext();) { 1129 Artifact childId = (Artifact) iterator.next(); 1130 configurationModel.unload(childId); 1131 removeConfigurationFromModel(childId); 1132 } 1133 1134 throw new LifecycleException("reload", newConfigurationId, results); 1135 } 1136 } finally { 1137 reloadingConfiguration = null; 1138 } 1139 } 1140 1141 // 1142 // reload as many child configurations as possible 1143 // 1144 Set skip = new HashSet(); 1145 for (Iterator iterator = reloadChildren.entrySet().iterator(); iterator.hasNext();) { 1146 Map.Entry entry = (Map.Entry) iterator.next(); 1147 Artifact configurationId = (Artifact) entry.getKey(); 1148 UnloadedConfiguration unloadedConfiguration = (UnloadedConfiguration) entry.getValue(); 1149 1150 // skip the configurations that have alredy failed or are children of failed configurations 1151 if (skip.contains(configurationId)) { 1152 continue; 1153 } 1154 1155 // try to load the configuation 1156 Configuration configuration = null; 1157 try { 1158 // get the correct resolved parent ids based on if we are loading with the new config id or the existing one 1159 LinkedHashSet resolvedParentIds; 1160 if (!reinstatedExisting) { 1161 resolvedParentIds = unloadedConfiguration.getResolvedParentIds(); 1162 } else { 1163 resolvedParentIds = (LinkedHashSet) existingParents.get(configurationId); 1164 } 1165 1166 // if the resolved parent ids is null, then we are not supposed to reload this configuration 1167 if (resolvedParentIds != null) { 1168 monitor.loading(configurationId); 1169 configuration = load(unloadedConfiguration.getConfigurationData(), resolvedParentIds, Collections.EMPTY_MAP); 1170 reloadingConfiguration = configuration; 1171 monitor.succeeded(configurationId); 1172 1173 // if the configuration was started before restart it 1174 if (started.contains(configurationId)) { 1175 monitor.starting(configurationId); 1176 start(configuration); 1177 monitor.succeeded(configurationId); 1178 results.addStarted(configurationId); 1179 } 1180 1181 // don't mark as loded until start completes as it may thow an exception 1182 results.addLoaded(configurationId); 1183 1184 configurations.put(configurationId, configuration); 1185 } else { 1186 removeConfigurationFromModel(configurationId); 1187 } 1188 } catch (Exception e) { 1189 // the configuraiton failed to restart 1190 results.addFailed(configurationId, e); 1191 monitor.failed(configurationId, e); 1192 skip.add(configurationId); 1193 1194 // unload the configuration if it was loaded and failed in start 1195 if (configuration != null) { 1196 unload(configuration); 1197 } 1198 1199 // officially unload the configuration in the model (without gc) 1200 LinkedHashSet unloadList = configurationModel.unload(configurationId, false); 1201 configurationModel.removeConfiguration(configurationId); 1202 1203 // all of the configurations to be unloaded must be in our unloaded list, or the model is corrupt 1204 if (!reloadChildren.keySet().containsAll(unloadList)) { 1205 throw new AssertionError("Configuration data model is corrupt. You must restart your server."); 1206 } 1207 1208 // add the children of the failed configuration to the results as unloaded 1209 for (Iterator iterator1 = unloadList.iterator(); iterator1.hasNext();) { 1210 Artifact failedId = (Artifact) iterator1.next(); 1211 1212 // if any of the failed configuration are in the reloaded set, the model is 1213 // corrupt because we loaded a child before a parent 1214 if (results.wasLoaded(failedId)) { 1215 throw new AssertionError("Configuration data model is corrupt. You must restart your server."); 1216 } 1217 1218 skip.add(failedId); 1219 } 1220 } finally { 1221 reloadingConfiguration = null; 1222 } 1223 } 1224 1225 // 1226 // If nothing failed, delete all the unloaded modules that weren't reloaded 1227 // 1228 if (!results.wasLoaded(existingConfigurationId) && !results.wasFailed(existingConfigurationId)) { 1229 try { 1230 uninstallConfiguration(existingConfigurationId); 1231 } catch (IOException e) { 1232 log.error("Unable to uninstall configuration " + existingConfigurationId, e); 1233 } 1234 } 1235 1236 monitor.finished(); 1237 if (results.wasFailed(newConfigurationId) || !results.wasLoaded(newConfigurationId)) { 1238 throw new LifecycleException("restart", newConfigurationId, results); 1239 } 1240 return results; 1241 } 1242 1243 protected void migrateConfiguration(Artifact oldName, Artifact newName, Configuration configuration, boolean running) throws NoSuchConfigException { 1244 } 1245 1246 private static LinkedHashSet getResolvedParentIds(Configuration configuration) { 1247 LinkedHashSet resolvedParentIds = new LinkedHashSet(); 1248 for (Iterator iterator = configuration.getClassParents().iterator(); iterator.hasNext();) { 1249 Configuration classParent = (Configuration) iterator.next(); 1250 resolvedParentIds.add(classParent.getId()); 1251 } 1252 for (Iterator iterator = configuration.getServiceParents().iterator(); iterator.hasNext();) { 1253 Configuration serviceParent = (Configuration) iterator.next(); 1254 resolvedParentIds.add(serviceParent.getId()); 1255 } 1256 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) { 1257 Configuration child = (Configuration) iterator.next(); 1258 resolvedParentIds.addAll(getResolvedParentIds(child)); 1259 } 1260 1261 return resolvedParentIds; 1262 } 1263 1264 public synchronized void uninstallConfiguration(Artifact configurationId) throws IOException, NoSuchConfigException { 1265 if (!configurationId.isResolved()) { 1266 throw new IllegalArgumentException("Artifact " + configurationId + " is not fully resolved"); 1267 } 1268 if (configurations.containsKey(configurationId)) { 1269 if (isRunning(configurationId)) { 1270 stopConfiguration(configurationId); 1271 } 1272 if (isLoaded((configurationId))) { 1273 unloadConfiguration(configurationId); 1274 } 1275 } 1276 1277 uninstall(configurationId); 1278 List storeSnapshot = getStoreList(); 1279 for (int i = 0; i < storeSnapshot.size(); i++) { 1280 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i); 1281 if (store.containsConfiguration(configurationId)) { 1282 store.uninstall(configurationId); 1283 } 1284 } 1285 1286 removeConfigurationFromModel(configurationId); 1287 notifyWatchers(configurationId); 1288 } 1289 1290 protected void uninstall(Artifact configurationId) { 1291 //child class can override this method 1292 } 1293 1294 private void notifyWatchers(Artifact id) { 1295 for (Iterator it = watchers.iterator(); it.hasNext();) { 1296 DeploymentWatcher watcher = (DeploymentWatcher) it.next(); 1297 watcher.undeployed(id); 1298 } 1299 } 1300 1301 public ArtifactResolver getArtifactResolver() { 1302 return artifactResolver; 1303 } 1304 1305 /** 1306 * this configuration manager never starts configurations. 1307 * 1308 * @return false 1309 */ 1310 public boolean isOnline() { 1311 return false; 1312 } 1313 1314 public void setOnline(boolean online) { 1315 } 1316 1317 protected List getStoreList() { 1318 return new ArrayList(stores); 1319 } 1320 1321 private static void addConfigurationsToMonitor(LifecycleMonitor monitor, LinkedHashSet configurations) { 1322 for (Iterator iterator = configurations.iterator(); iterator.hasNext();) { 1323 Artifact configurationId = (Artifact) iterator.next(); 1324 monitor.addConfiguration(configurationId); 1325 } 1326 } 1327 1328 private static LinkedHashSet reverse(LinkedHashSet set) { 1329 ArrayList reverseList = new ArrayList(set); 1330 Collections.reverse(reverseList); 1331 set = new LinkedHashSet(reverseList); 1332 return set; 1333 } 1334 1335 private static LinkedHashMap reverse(LinkedHashMap map) { 1336 ArrayList reverseEntrySet = new ArrayList(map.entrySet()); 1337 Collections.reverse(reverseEntrySet); 1338 1339 map = new LinkedHashMap(reverseEntrySet.size()); 1340 for (Iterator iterator = reverseEntrySet.iterator(); iterator.hasNext();) { 1341 Map.Entry entry = (Map.Entry) iterator.next(); 1342 Object key = entry.getKey(); 1343 Object value = entry.getValue(); 1344 map.put(key, value); 1345 } 1346 return map; 1347 } 1348 1349 public static final GBeanInfo GBEAN_INFO; 1350 1351 static { 1352 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(SimpleConfigurationManager.class, "ConfigurationManager"); 1353 infoFactory.addReference("Stores", ConfigurationStore.class, "ConfigurationStore"); 1354 infoFactory.addReference("ArtifactResolver", ArtifactResolver.class, "ArtifactResolver"); 1355 infoFactory.addReference("Repositories", Repository.class, "Repository"); 1356 infoFactory.addReference("Watchers", DeploymentWatcher.class); 1357 infoFactory.addInterface(ConfigurationManager.class); 1358 infoFactory.setConstructor(new String[]{"Stores", "ArtifactResolver", "Repositories", "Watchers"}); 1359 GBEAN_INFO = infoFactory.getBeanInfo(); 1360 } 1361 1362 public static GBeanInfo getGBeanInfo() { 1363 return GBEAN_INFO; 1364 } 1365 1366 }