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 java.util.Collections;
11 import java.util.Dictionary;
12 import java.util.Enumeration;
13 import java.util.Hashtable;
14 import java.util.List;
15 import org.apache.aries.blueprint.NamespaceHandler;
16 import org.apache.aries.blueprint.services.BlueprintExtenderService;
17 import org.apache.aries.util.AriesFrameworkUtil;
18 import org.opendaylight.controller.blueprint.ext.OpendaylightNamespaceHandler;
19 import org.osgi.framework.Bundle;
20 import org.osgi.framework.BundleActivator;
21 import org.osgi.framework.BundleContext;
22 import org.osgi.framework.BundleEvent;
23 import org.osgi.framework.ServiceReference;
24 import org.osgi.framework.ServiceRegistration;
25 import org.osgi.service.blueprint.container.EventConstants;
26 import org.osgi.service.event.Event;
27 import org.osgi.service.event.EventHandler;
28 import org.osgi.util.tracker.BundleTracker;
29 import org.osgi.util.tracker.BundleTrackerCustomizer;
30 import org.osgi.util.tracker.ServiceTracker;
31 import org.osgi.util.tracker.ServiceTrackerCustomizer;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * This class is created in bundle activation and scans ACTIVE bundles for blueprint XML files located under
37 * the well-known org/opendaylight/blueprint/ path and deploys the XML files via the Aries
38 * BlueprintExtenderService. This path differs from the standard OSGI-INF/blueprint path to allow for
39 * controlled deployment of blueprint containers in an orderly manner.
41 * @author Thomas Pantelis
43 public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCustomizer<Bundle>, EventHandler {
44 private static final Logger LOG = LoggerFactory.getLogger(BlueprintBundleTracker.class);
45 private static final String BLUEPRINT_FILE_PATH = "org/opendaylight/blueprint/";
46 private static final String BLUEPRINT_FLE_PATTERN = "*.xml";
48 private ServiceTracker<BlueprintExtenderService, BlueprintExtenderService> serviceTracker;
49 private BundleTracker<Bundle> bundleTracker;
50 private volatile BlueprintExtenderService blueprintExtenderService;
51 private volatile ServiceRegistration<?> blueprintContainerRestartReg;
52 private ServiceRegistration<?> eventHandlerReg;
53 private ServiceRegistration<?> namespaceReg;
56 * Implemented from BundleActivator.
59 public void start(BundleContext context) {
60 LOG.info("Starting {}", getClass().getSimpleName());
62 registerBlueprintEventHandler(context);
64 registerNamespaceHandler(context);
66 bundleTracker = new BundleTracker<>(context, Bundle.ACTIVE, this);
68 serviceTracker = new ServiceTracker<>(context, BlueprintExtenderService.class.getName(),
69 new ServiceTrackerCustomizer<BlueprintExtenderService, BlueprintExtenderService>() {
71 public BlueprintExtenderService addingService(
72 ServiceReference<BlueprintExtenderService> reference) {
73 blueprintExtenderService = reference.getBundle().getBundleContext().getService(reference);
76 LOG.debug("Got BlueprintExtenderService");
78 blueprintContainerRestartReg = context.registerService(
79 BlueprintContainerRestartService.class.getName(),
80 new BlueprintContainerRestartServiceImpl(blueprintExtenderService), new Hashtable<>());
82 return blueprintExtenderService;
86 public void modifiedService(ServiceReference<BlueprintExtenderService> reference,
87 BlueprintExtenderService service) {
91 public void removedService(ServiceReference<BlueprintExtenderService> reference,
92 BlueprintExtenderService service) {
95 serviceTracker.open();
98 private void registerNamespaceHandler(BundleContext context) {
99 Dictionary<String, Object> props = new Hashtable<>();
100 props.put("osgi.service.blueprint.namespace", OpendaylightNamespaceHandler.NAMESPACE_1_0_0);
101 namespaceReg = context.registerService(NamespaceHandler.class.getName(),
102 new OpendaylightNamespaceHandler(), props);
105 private void registerBlueprintEventHandler(BundleContext context) {
106 Dictionary<String, Object> props = new Hashtable<>();
107 props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC, EventConstants.TOPIC_CREATED);
108 eventHandlerReg = context.registerService(EventHandler.class.getName(), this, props);
112 * Implemented from BundleActivator.
115 public void stop(BundleContext context) {
116 bundleTracker.close();
117 serviceTracker.close();
119 AriesFrameworkUtil.safeUnregisterService(eventHandlerReg);
120 AriesFrameworkUtil.safeUnregisterService(namespaceReg);
121 AriesFrameworkUtil.safeUnregisterService(blueprintContainerRestartReg);
125 * Implemented from BundleActivator.
128 public Bundle addingBundle(Bundle bundle, BundleEvent event) {
129 modifiedBundle(bundle, event, bundle);
134 * Implemented from BundleActivator.
137 public void modifiedBundle(Bundle bundle, BundleEvent event, Bundle object) {
138 if(bundle.getState() == Bundle.ACTIVE) {
139 List<Object> paths = findBlueprintPaths(bundle);
141 if(!paths.isEmpty()) {
142 LOG.info("Creating blueprint container for bundle {} with paths {}", bundle, paths);
144 blueprintExtenderService.createContainer(bundle, paths);
150 * Implemented from BundleActivator.
153 public void removedBundle(Bundle bundle, BundleEvent event, Bundle object) {
154 // BlueprintExtenderService will handle this.
158 * Implemented from EventHandler to listen for blueprint events.
163 public void handleEvent(Event event) {
164 if(EventConstants.TOPIC_CREATED.equals(event.getTopic())) {
165 LOG.info("Blueprint container for bundle {} was successfully created",
166 event.getProperty(EventConstants.BUNDLE));
170 @SuppressWarnings({ "rawtypes", "unchecked" })
171 static List<Object> findBlueprintPaths(Bundle bundle) {
172 Enumeration<?> e = bundle.findEntries(BLUEPRINT_FILE_PATH, BLUEPRINT_FLE_PATTERN, false);
174 return Collections.emptyList();
176 return Collections.list((Enumeration)e);