From: Tom Pantelis Date: Tue, 5 Apr 2016 04:30:37 +0000 (-0400) Subject: Add Blueprint bundle tracker X-Git-Tag: release/boron~242 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=0aabbfe6127ab85eedf576a82f95805ddfc051f0 Add Blueprint bundle tracker Added an initial blueprint bundle and BlueprintBundleTracker which scans ACTIVE bundles for blueprint XML files located under the well-known org/opendaylight/blueprint/ path and deploys the XML files via the Aries BlueprintExtenderService. This path differs from the standard OSGI-INF/blueprint path to allow for controlled deployment of blueprint containers in an orderly manner. Change-Id: I21fd5aeb1d9ccd609caa8ea89bd66648fee5ad97 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/blueprint/pom.xml b/opendaylight/blueprint/pom.xml new file mode 100644 index 0000000000..511a185cd4 --- /dev/null +++ b/opendaylight/blueprint/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + + org.opendaylight.controller + commons.opendaylight + 1.7.0-SNAPSHOT + ../commons/opendaylight + + + blueprint + bundle + ${project.artifactId} + 0.5.0-SNAPSHOT + + + + com.google.guava + guava + + + org.apache.aries.blueprint + org.apache.aries.blueprint.core + 1.4.2 + + + org.osgi + org.osgi.core + + + org.osgi + org.osgi.compendium + + + org.slf4j + slf4j-api + + + junit + junit + test + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.opendaylight.controller.blueprint.BlueprintBundleTracker + + + + + + + diff --git a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java new file mode 100644 index 0000000000..98e31e826b --- /dev/null +++ b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.blueprint; + +import java.util.Collections; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import org.apache.aries.blueprint.services.BlueprintExtenderService; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.blueprint.container.EventConstants; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; +import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.BundleTrackerCustomizer; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is created in bundle activation and scans ACTIVE bundles for blueprint XML files located under + * the well-known org/opendaylight/blueprint/ path and deploys the XML files via the Aries + * BlueprintExtenderService. This path differs from the standard OSGI-INF/blueprint path to allow for + * controlled deployment of blueprint containers in an orderly manner. + * + * @author Thomas Pantelis + */ +public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCustomizer, EventHandler { + private static final Logger LOG = LoggerFactory.getLogger(BlueprintBundleTracker.class); + private static final String BLUEPRINT_FILE_PATH = "org/opendaylight/blueprint/"; + private static final String BLUEPRINT_FLE_PATTERN = "*.xml"; + + private ServiceTracker serviceTracker; + private BundleTracker bundleTracker; + private volatile BlueprintExtenderService blueprintExtenderService; + private ServiceRegistration eventHandlerReg; + + /** + * Implemented from BundleActivator. + */ + @Override + public void start(BundleContext context) { + LOG.info("Starting {}", getClass().getSimpleName()); + + // Register EventHandler for blueprint events + + Dictionary props = new Hashtable<>(); + props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC, EventConstants.TOPIC_CREATED); + eventHandlerReg = context.registerService(EventHandler.class.getName(), this, props); + + bundleTracker = new BundleTracker<>(context, Bundle.ACTIVE, this); + + serviceTracker = new ServiceTracker<>(context, BlueprintExtenderService.class.getName(), + new ServiceTrackerCustomizer() { + @Override + public BlueprintExtenderService addingService( + ServiceReference reference) { + blueprintExtenderService = reference.getBundle().getBundleContext().getService(reference); + bundleTracker.open(); + + LOG.debug("Got BlueprintExtenderService"); + + return blueprintExtenderService; + } + + @Override + public void modifiedService(ServiceReference reference, + BlueprintExtenderService service) { + } + + @Override + public void removedService(ServiceReference reference, + BlueprintExtenderService service) { + } + }); + serviceTracker.open(); + } + + /** + * Implemented from BundleActivator. + */ + @Override + public void stop(BundleContext context) { + bundleTracker.close(); + serviceTracker.close(); + eventHandlerReg.unregister(); + } + + /** + * Implemented from BundleActivator. + */ + @Override + public Bundle addingBundle(Bundle bundle, BundleEvent event) { + modifiedBundle(bundle, event, bundle); + return bundle; + } + + /** + * Implemented from BundleActivator. + */ + @Override + public void modifiedBundle(Bundle bundle, BundleEvent event, Bundle object) { + if(bundle.getState() == Bundle.ACTIVE) { + List paths = findBlueprintPaths(bundle); + + if(!paths.isEmpty()) { + LOG.info("Creating blueprint container for bundle {} with paths {}", bundle, paths); + + blueprintExtenderService.createContainer(bundle, paths); + } + } + } + + /** + * Implemented from BundleActivator. + */ + @Override + public void removedBundle(Bundle bundle, BundleEvent event, Bundle object) { + // BlueprintExtenderService will handle this. + } + + /** + * Implemented from EventHandler to listen for blueprint events. + * + * @param event + */ + @Override + public void handleEvent(Event event) { + if(EventConstants.TOPIC_CREATED.equals(event.getTopic())) { + LOG.info("Blueprint container for bundle {} was successfully created", + event.getProperty(EventConstants.BUNDLE)); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + static List findBlueprintPaths(Bundle bundle) { + Enumeration e = bundle.findEntries(BLUEPRINT_FILE_PATH, BLUEPRINT_FLE_PATTERN, false); + if(e == null) { + return Collections.emptyList(); + } else { + return Collections.list((Enumeration)e); + } + } +} diff --git a/pom.xml b/pom.xml index c082be41b6..28757fd255 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,8 @@ opendaylight/model + opendaylight/blueprint + opendaylight/commons/protocol-framework opendaylight/commons/checkstyle