2 * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.blueprint;
10 import com.google.common.util.concurrent.ThreadFactoryBuilder;
11 import java.util.ArrayList;
12 import java.util.LinkedHashSet;
13 import java.util.List;
15 import java.util.concurrent.ExecutorService;
16 import java.util.concurrent.Executors;
17 import org.apache.aries.blueprint.services.BlueprintExtenderService;
18 import org.osgi.framework.Bundle;
19 import org.osgi.framework.ServiceReference;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
23 /** Implementation of the BlueprintContainerRestartService.
25 * @author Thomas Pantelis
27 class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintContainerRestartService {
28 private static final Logger LOG = LoggerFactory.getLogger(BlueprintContainerRestartServiceImpl.class);
30 private final ExecutorService restartExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().
31 setDaemon(true).setNameFormat("BlueprintContainerRestartService").build());
32 private final BlueprintExtenderService blueprintExtenderService;
34 BlueprintContainerRestartServiceImpl(BlueprintExtenderService blueprintExtenderService) {
35 this.blueprintExtenderService = blueprintExtenderService;
39 public void restartContainerAndDependents(final Bundle bundle) {
40 LOG.debug("restartContainerAndDependents for bundle {}", bundle);
42 restartExecutor.execute(new Runnable() {
45 restartContainerAndDependentsInternal(bundle);
51 private void restartContainerAndDependentsInternal(Bundle forBundle) {
52 Set<Bundle> containerBundlesSet = new LinkedHashSet<>();
53 findDependentContainersRecursively(forBundle, containerBundlesSet);
55 List<Bundle> containerBundles = new ArrayList<>(containerBundlesSet);
57 LOG.info("Restarting blueprint containers for bundle {} and its dependent bundles {}", forBundle,
58 containerBundles.subList(1, containerBundles.size()));
60 // Destroy the containers in reverse order with 'forBundle' last, ie bottom-up in the service tree.
61 for(int i = containerBundles.size() - 1; i >= 0; i--) {
62 Bundle bundle = containerBundles.get(i);
63 blueprintExtenderService.destroyContainer(bundle, blueprintExtenderService.getContainer(bundle));
66 // Restart the containers top-down starting with 'forBundle'.
67 for(Bundle bundle: containerBundles) {
68 List<Object> paths = BlueprintBundleTracker.findBlueprintPaths(bundle);
70 LOG.info("Restarting blueprint container for bundle {} with paths {}", bundle, paths);
72 blueprintExtenderService.createContainer(bundle, paths);
77 * Recursively finds the services registered by the given bundle and the bundles using those services.
78 * User bundles that have an associated blueprint container are added to containerBundles.
80 * @param bundle the bundle to traverse
81 * @param containerBundles the current set of bundles containing blueprint containers
83 private void findDependentContainersRecursively(Bundle bundle, Set<Bundle> containerBundles) {
84 if(containerBundles.contains(bundle)) {
88 containerBundles.add(bundle);
89 ServiceReference<?>[] references = bundle.getRegisteredServices();
90 if (references != null) {
91 for (ServiceReference<?> reference : references) {
92 Bundle[] usingBundles = reference.getUsingBundles();
93 if(usingBundles != null) {
94 for(Bundle usingBundle: usingBundles) {
95 if(blueprintExtenderService.getContainer(usingBundle) != null) {
96 findDependentContainersRecursively(usingBundle, containerBundles);
105 public void close() {
106 restartExecutor.shutdownNow();