From: Tony Tkacik Date: Thu, 17 Oct 2013 08:26:47 +0000 (+0200) Subject: Updated BindingAware Activators to prevent premature initialization X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~608 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=997fe28af0196c9fe4fc70ec9c0494d9be1d5a25 Updated BindingAware Activators to prevent premature initialization Fixes a bug when BindingAwareActivators loaded in wrong order and tried to retrieve MD-SAL broker before broker bundle was started. Change-Id: I87f807974b8581a14b387928a52c2ee2fd83208c Signed-off-by: Tony Tkacik --- diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareConsumer.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareConsumer.java index f6c9df23f2..fc145c8b16 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareConsumer.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareConsumer.java @@ -12,63 +12,11 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; -public abstract class AbstractBindingAwareConsumer implements BindingAwareConsumer,BundleActivator { +public abstract class AbstractBindingAwareConsumer extends AbstractBrokerAwareActivator implements BindingAwareConsumer { @Override - public final void start(BundleContext context) throws Exception { - startImpl(context); - ServiceReference brokerRef = context.getServiceReference(BindingAwareBroker.class); - BindingAwareBroker broker = context.getService(brokerRef); + protected final void onBrokerAvailable(BindingAwareBroker broker, BundleContext context) { broker.registerConsumer(this, context); - //context.ungetService(brokerRef); - } - - /** - * Called when this bundle is started (before - * {@link #onSessionInitiated(ProviderContext)} so the Framework can perform - * the bundle-specific activities necessary to start this bundle. This - * method can be used to register services or to allocate any resources that - * this bundle needs. - * - *

- * This method must complete and return to its caller in a timely manner. - * - * @param context - * The execution context of the bundle being started. - * @throws Exception - * If this method throws an exception, this bundle is marked as - * stopped and the Framework will remove this bundle's - * listeners, unregister all services registered by this bundle, - * and release all services used by this bundle. - */ - protected void startImpl(BundleContext context) { - // NOOP - } - - /** - * Called when this bundle is stopped so the Framework can perform the - * bundle-specific activities necessary to stop the bundle. In general, this - * method should undo the work that the {@code BundleActivator.start} method - * started. There should be no active threads that were started by this - * bundle when this bundle returns. A stopped bundle must not call any - * Framework objects. - * - *

- * This method must complete and return to its caller in a timely manner. - * - * @param context The execution context of the bundle being stopped. - * @throws Exception If this method throws an exception, the bundle is still - * marked as stopped, and the Framework will remove the bundle's - * listeners, unregister all services registered by the bundle, and - * release all services used by the bundle. - */ - protected void stopImpl(BundleContext context) { - // NOOP - } - - @Override - public final void stop(BundleContext context) throws Exception { - stopImpl(context); } } diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareProvider.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareProvider.java index b1a0fe0c28..9d3bff4ef8 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareProvider.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareProvider.java @@ -17,31 +17,10 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; -public abstract class AbstractBindingAwareProvider implements BindingAwareProvider, BundleActivator { - - /** - * Initializes the bundle. - * - * Implementation of initialization get's the Binding Aware Broker from - * service registry and register itself as a {@link BindingAwareProvider} - * - * Callback order is: - *

    - *
  1. {@link #startImpl(BundleContext)} - *
  2. {@link #onSessionInitiated(ProviderContext)} - *
  3. Registration of global {@link RpcService} implementations returned by - * {@link #getImplementations()} - *
  4. Registration of {@link ProviderFunctionality} implementations - * returned by {@link #getFunctionality()} - *
- * - */ +public abstract class AbstractBindingAwareProvider extends AbstractBrokerAwareActivator implements BindingAwareProvider { + @Override - public final void start(BundleContext context) throws Exception { - startImpl(context); - ServiceReference brokerRef = context.getServiceReference(BindingAwareBroker.class); - BindingAwareBroker broker = context.getService(brokerRef); - + protected final void onBrokerAvailable(BindingAwareBroker broker, BundleContext context) { ProviderContext ctx = broker.registerProvider(this, context); registerRpcImplementations(ctx); registerFunctionality(ctx); @@ -69,62 +48,6 @@ public abstract class AbstractBindingAwareProvider implements BindingAwareProvid } - /** - * Called when this bundle is started (before - * {@link #onSessionInitiated(ProviderContext)} so the Framework can perform - * the bundle-specific activities necessary to start this bundle. This - * method can be used to register services or to allocate any resources that - * this bundle needs. - * - *

- * This method must complete and return to its caller in a timely manner. - * - * @param context - * The execution context of the bundle being started. - * @throws Exception - * If this method throws an exception, this bundle is marked as - * stopped and the Framework will remove this bundle's - * listeners, unregister all services registered by this bundle, - * and release all services used by this bundle. - */ - protected void startImpl(BundleContext context) { - // NOOP - } - - /** - * Called when this bundle is stopped so the Framework can perform the - * bundle-specific activities necessary to stop the bundle. In general, this - * method should undo the work that the {@code BundleActivator.start} method - * started. There should be no active threads that were started by this - * bundle when this bundle returns. A stopped bundle must not call any - * Framework objects. - * - *

- * This method must complete and return to its caller in a timely manner. - * - * @param context The execution context of the bundle being stopped. - * @throws Exception If this method throws an exception, the bundle is still - * marked as stopped, and the Framework will remove the bundle's - * listeners, unregister all services registered by the bundle, and - * release all services used by the bundle. - */ - protected void stopImpl(BundleContext context) { - // NOOP - } - - /** - * Bundle stop callback - * - * - * Custom implementation of bundle stop could be carried by overriding - * {@link #stopImpl(BundleContext)} method. - * - */ - @Override - public final void stop(BundleContext context) throws Exception { - stopImpl(context); - } - @Override public Collection getFunctionality() { return Collections.emptySet(); diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBrokerAwareActivator.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBrokerAwareActivator.java new file mode 100644 index 0000000000..d1a3f85f94 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBrokerAwareActivator.java @@ -0,0 +1,115 @@ +package org.opendaylight.controller.sal.binding.api; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; + +public abstract class AbstractBrokerAwareActivator implements BundleActivator { + + private static final ExecutorService mdActivationPool = Executors.newCachedThreadPool(); + private BundleContext context; + private ServiceTracker tracker; + private BindingAwareBroker broker; + private ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer() { + + @Override + public BindingAwareBroker addingService(ServiceReference reference) { + broker = context.getService(reference); + mdActivationPool.execute(new Runnable() { + + @Override + public void run() { + onBrokerAvailable(broker, context);; + } + }); + return broker; + } + + @Override + public void modifiedService(ServiceReference reference, BindingAwareBroker service) { + // TODO Auto-generated method stub + + } + + @Override + public void removedService(ServiceReference reference, BindingAwareBroker service) { + // TODO Auto-generated method stub + + } + + }; + + + @Override + public final void start(BundleContext context) throws Exception { + this.context = context; + startImpl(context); + tracker = new ServiceTracker<>(context, BindingAwareBroker.class, customizer); + tracker.open(); + + } + + + + @Override + public final void stop(BundleContext context) throws Exception { + tracker.close(); + stopImpl(context); + } + + + /** + * Called when this bundle is started (before + * {@link #onSessionInitiated(ProviderContext)} so the Framework can perform + * the bundle-specific activities necessary to start this bundle. This + * method can be used to register services or to allocate any resources that + * this bundle needs. + * + *

+ * This method must complete and return to its caller in a timely manner. + * + * @param context + * The execution context of the bundle being started. + * @throws Exception + * If this method throws an exception, this bundle is marked as + * stopped and the Framework will remove this bundle's + * listeners, unregister all services registered by this bundle, + * and release all services used by this bundle. + */ + protected void startImpl(BundleContext context) { + // NOOP + } + + /** + * Called when this bundle is stopped so the Framework can perform the + * bundle-specific activities necessary to stop the bundle. In general, this + * method should undo the work that the {@code BundleActivator.start} method + * started. There should be no active threads that were started by this + * bundle when this bundle returns. A stopped bundle must not call any + * Framework objects. + * + *

+ * This method must complete and return to its caller in a timely manner. + * + * @param context The execution context of the bundle being stopped. + * @throws Exception If this method throws an exception, the bundle is still + * marked as stopped, and the Framework will remove the bundle's + * listeners, unregister all services registered by the bundle, and + * release all services used by the bundle. + */ + protected void stopImpl(BundleContext context) { + // NOOP + } + + + protected abstract void onBrokerAvailable(BindingAwareBroker broker, BundleContext context); + + protected void onBrokerRemoved(BindingAwareBroker broker, BundleContext context) { + + } +}