Updated BindingAware Activators to prevent premature initialization 55/1955/3
authorTony Tkacik <ttkacik@cisco.com>
Thu, 17 Oct 2013 08:26:47 +0000 (10:26 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 19 Oct 2013 18:53:33 +0000 (18:53 +0000)
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 <ttkacik@cisco.com>
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareConsumer.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBindingAwareProvider.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/AbstractBrokerAwareActivator.java [new file with mode: 0644]

index f6c9df23f2fde698c1403f806c845bba61e4a30a..fc145c8b16e0d9dff7e0c29e480ff5fe9935f4dd 100644 (file)
@@ -12,63 +12,11 @@ import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
 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
 
     @Override
-    public final void start(BundleContext context) throws Exception {
-        startImpl(context);
-        ServiceReference<BindingAwareBroker> brokerRef = context.getServiceReference(BindingAwareBroker.class);
-        BindingAwareBroker broker = context.getService(brokerRef);
+    protected final void onBrokerAvailable(BindingAwareBroker broker, BundleContext context) {
         broker.registerConsumer(this, 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.
-     * 
-     * <p>
-     * 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.
-     * 
-     * <p>
-     * 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);
     }
 
 }
     }
 
 }
index b1a0fe0c286075420b5ae02744dc5ee5dcb5b183..9d3bff4ef8b9d4d954f3f10b31d3789d655ad59e 100644 (file)
@@ -17,31 +17,10 @@ import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
 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:
-     * <ol>
-     * <li>{@link #startImpl(BundleContext)}
-     * <li>{@link #onSessionInitiated(ProviderContext)}
-     * <li>Registration of global {@link RpcService} implementations returned by
-     * {@link #getImplementations()}
-     * <li>Registration of {@link ProviderFunctionality} implementations
-     * returned by {@link #getFunctionality()}
-     * </ol>
-     * 
-     */
+public abstract class AbstractBindingAwareProvider extends AbstractBrokerAwareActivator implements BindingAwareProvider {
+    
     @Override
     @Override
-    public final void start(BundleContext context) throws Exception {
-        startImpl(context);
-        ServiceReference<BindingAwareBroker> 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);
         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.
-     * 
-     * <p>
-     * 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.
-     * 
-     * <p>
-     * 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<? extends ProviderFunctionality> getFunctionality() {
         return Collections.emptySet();
     @Override
     public Collection<? extends ProviderFunctionality> 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 (file)
index 0000000..d1a3f85
--- /dev/null
@@ -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<BindingAwareBroker, BindingAwareBroker> tracker;
+    private BindingAwareBroker broker;
+    private ServiceTrackerCustomizer<BindingAwareBroker, BindingAwareBroker> customizer = new ServiceTrackerCustomizer<BindingAwareBroker, BindingAwareBroker>() {
+        
+        @Override
+        public BindingAwareBroker addingService(ServiceReference<BindingAwareBroker> reference) {
+            broker = context.getService(reference);
+            mdActivationPool.execute(new Runnable() {
+                
+                @Override
+                public void run() {
+                    onBrokerAvailable(broker, context);;
+                }
+            });
+            return broker;
+        }
+        
+        @Override
+        public void modifiedService(ServiceReference<BindingAwareBroker> reference, BindingAwareBroker service) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        @Override
+        public void removedService(ServiceReference<BindingAwareBroker> 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.
+     * 
+     * <p>
+     * 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.
+     * 
+     * <p>
+     * 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) {
+        
+    }
+}