Bug 7736 - Forwarding Rules application cluster singleton id should not use the same... 25/52225/2
authorJon Castro <castro.jon@gmail.com>
Mon, 6 Feb 2017 23:35:13 +0000 (10:35 +1100)
committerAnil Vishnoi <vishnoianil@gmail.com>
Thu, 23 Feb 2017 21:38:01 +0000 (13:38 -0800)
Change-Id: Ie82b2d7d23444927375ed5b63f5e765f3277ed00
Signed-off-by: Jon Castro <castro.jon@gmail.com>
13 files changed:
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java
applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml
applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java

index 54360a005dee373773f0d9fc2ff5f98da867413a..e6876ae401c461cc48502886f73bae9d052e4149 100644 (file)
@@ -25,25 +25,26 @@ public class DeviceMastership implements ClusterSingletonService, AutoCloseable
     private static final Logger LOG = LoggerFactory.getLogger(DeviceMastership.class);
     private final NodeId nodeId;
     private final ServiceGroupIdentifier identifier;
-    private final ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
+    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
     private boolean deviceMastered;
 
     public DeviceMastership(final NodeId nodeId, final ClusterSingletonServiceProvider clusterSingletonService) {
         this.nodeId = nodeId;
         this.identifier = ServiceGroupIdentifier.create(nodeId.getValue());
         this.deviceMastered = false;
-        clusterSingletonServiceRegistration = clusterSingletonService.registerClusterSingletonService(this);
+        this.clusterSingletonServiceProvider = clusterSingletonService;
     }
 
     @Override
     public void instantiateServiceInstance() {
-        LOG.debug("FRM started for: {}", nodeId.getValue());
+        LOG.info("FRM started for: {}", nodeId.getValue());
         deviceMastered = true;
     }
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
-        LOG.debug("FRM stopped for: {}", nodeId.getValue());
+        LOG.info("FRM stopped for: {}", nodeId.getValue());
         deviceMastered = false;
         return Futures.immediateFuture(null);
     }
@@ -68,4 +69,8 @@ public class DeviceMastership implements ClusterSingletonService, AutoCloseable
         return deviceMastered;
     }
 
+    public void registerClusterSingletonService() {
+        LOG.info("Registering FRM as a cluster singleton service listner for service id : {}",getIdentifier());
+        clusterSingletonServiceRegistration = clusterSingletonServiceProvider.registerClusterSingletonService(this);
+    }
 }
index dd7c2721c7093830836384ac065dfaa54a05c881..2286338b07934acbd655416532676b33995e72f9 100644 (file)
@@ -10,35 +10,41 @@ package org.opendaylight.openflowplugin.applications.frm.impl;
 
 import com.google.common.annotations.VisibleForTesting;
 import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Manager for clustering service registrations of {@link DeviceMastership}.
  */
-public class DeviceMastershipManager {
+public class DeviceMastershipManager implements OpendaylightInventoryListener, AutoCloseable{
     private static final Logger LOG = LoggerFactory.getLogger(DeviceMastershipManager.class);
     private final ClusterSingletonServiceProvider clusterSingletonService;
+    private final ListenerRegistration<?> notifListenerRegistration;
     private final ConcurrentHashMap<NodeId, DeviceMastership> deviceMasterships = new ConcurrentHashMap();
 
-    public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService) {
+    public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService,
+                                   final NotificationProviderService notificationService) {
         this.clusterSingletonService = clusterSingletonService;
+        this.notifListenerRegistration = notificationService.registerNotificationListener(this);
     }
 
     public void onDeviceConnected(final NodeId nodeId) {
-        LOG.debug("FRM service registered for: {}", nodeId.getValue());
-        final DeviceMastership mastership = new DeviceMastership(nodeId, clusterSingletonService);
-        deviceMasterships.put(nodeId, mastership);
+        //No-op
     }
 
     public void onDeviceDisconnected(final NodeId nodeId) {
-        final DeviceMastership mastership = deviceMasterships.remove(nodeId);
-        if (mastership != null) {
-            mastership.close();
-        }
-        LOG.debug("FRM service unregistered for: {}", nodeId.getValue());
+        //No-op
     }
 
     public boolean isDeviceMastered(final NodeId nodeId) {
@@ -49,4 +55,40 @@ public class DeviceMastershipManager {
     ConcurrentHashMap<NodeId, DeviceMastership> getDeviceMasterships() {
         return deviceMasterships;
     }
+
+    @Override
+    public void onNodeUpdated(NodeUpdated notification) {
+        LOG.debug("NodeUpdate notification received : {}", notification);
+        DeviceMastership membership = deviceMasterships.computeIfAbsent(notification.getId(), device ->
+                new DeviceMastership(notification.getId(), clusterSingletonService));
+        membership.registerClusterSingletonService();
+    }
+
+    @Override
+    public void onNodeConnectorUpdated(NodeConnectorUpdated notification) {
+        //Not published by plugin
+    }
+
+    @Override
+    public void onNodeRemoved(NodeRemoved notification) {
+        LOG.debug("NodeRemoved notification received : {}", notification);
+        NodeId nodeId = notification.getNodeRef().getValue().firstKeyOf(Node.class).getId();
+        final DeviceMastership mastership = deviceMasterships.remove(nodeId);
+        if (mastership != null) {
+            mastership.close();
+            LOG.info("Unregistered FRM cluster singleton service for service id : {}", nodeId.getValue());
+        }
+    }
+
+    @Override
+    public void onNodeConnectorRemoved(NodeConnectorRemoved notification) {
+        //Not published by plugin
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (notifListenerRegistration != null) {
+            notifListenerRegistration.close();
+        }
+    }
 }
index 61665cb59b587510631603ab100d5b7baba88e73..093ed96782e1ddd77cb59b18e48635f754be0fc4 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
@@ -74,16 +75,20 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
     private final ForwardingRulesManagerConfig forwardingRulesManagerConfig;
     private FlowNodeConnectorInventoryTranslatorImpl flowNodeConnectorInventoryTranslatorImpl;
     private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private final NotificationProviderService notificationService;
     private DeviceMastershipManager deviceMastershipManager;
 
     public ForwardingRulesManagerImpl(final DataBroker dataBroker,
                                       final RpcConsumerRegistry rpcRegistry,
                                       final ForwardingRulesManagerConfig config,
-                                      final ClusterSingletonServiceProvider clusterSingletonService) {
+                                      final ClusterSingletonServiceProvider clusterSingletonService,
+                                      final NotificationProviderService notificationService) {
         this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
         this.forwardingRulesManagerConfig = Preconditions.checkNotNull(config, "Configuration for FRM cannot be null");
         this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonService,
                 "ClusterSingletonService provider can not be null");
+        this.notificationService = Preconditions.checkNotNull(notificationService, "Notification publisher service is" +
+                " not available");
 
         Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
 
@@ -99,7 +104,8 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
 
     @Override
     public void start() {
-        this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider);
+        this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider,
+                notificationService);
         this.flowListener = new FlowForwarder(this, dataService);
         this.groupListener = new GroupForwarder(this, dataService);
         this.meterListener = new MeterForwarder(this, dataService);
@@ -132,6 +138,9 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
             this.nodeListener.close();
             this.nodeListener = null;
         }
+        if (deviceMastershipManager != null) {
+            deviceMastershipManager.close();
+        }
     }
 
     @Override
index b6f154e06524e1cca1ad31685f648da321d310da..c7d81bdc0213e165b918b736508f7a142e1c9387 100644 (file)
@@ -5,6 +5,7 @@
 
   <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
   <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+  <reference id="notificationService" interface="org.opendaylight.controller.sal.binding.api.NotificationProviderService"/>
   <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
   <odl:clustered-app-config id="frmConfig"
@@ -16,5 +17,6 @@
     <argument ref="rpcRegistry"/>
     <argument ref="frmConfig"/>
     <argument ref="clusterSingletonService"/>
+    <argument ref="notificationService"/>
   </bean>
 </blueprint>
\ No newline at end of file
index 870eb6be1bb8542eb6ae6965148a15e24769542f..31a83f605c175b375b5eeafc6a58632a6bec9822 100644 (file)
@@ -16,10 +16,18 @@ import org.mockito.Matchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
  * Test for {@link DeviceMastershipManager}.
@@ -32,10 +40,13 @@ public class DeviceMastershipManagerTest {
     private ClusterSingletonServiceRegistration registration;
     @Mock
     private ClusterSingletonServiceProvider clusterSingletonService;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() throws Exception {
-        deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService);
+        deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService,
+                notificationService);
         Mockito.when(clusterSingletonService.registerClusterSingletonService(Matchers.<ClusterSingletonService>any()))
                 .thenReturn(registration);
     }
@@ -44,22 +55,29 @@ public class DeviceMastershipManagerTest {
     public void testOnDeviceConnectedAndDisconnected() throws Exception {
         // no context
         Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
-        // create context - register
-        deviceMastershipManager.onDeviceConnected(NODE_ID);
+        NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+        nodeUpdatedBuilder.setId(NODE_ID);
+        deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
         DeviceMastership serviceInstance = deviceMastershipManager.getDeviceMasterships().get(NODE_ID);
         Assert.assertNotNull(serviceInstance);
-        Mockito.verify(clusterSingletonService).registerClusterSingletonService(serviceInstance);
         // destroy context - unregister
         deviceMastershipManager.onDeviceDisconnected(NODE_ID);
+        Assert.assertNotNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
+        NodeRemovedBuilder nodeRemovedBuilder = new NodeRemovedBuilder();
+        InstanceIdentifier<Node> nodeIId = InstanceIdentifier.create(Nodes.class).
+                child(Node.class, new NodeKey(NODE_ID));
+        nodeRemovedBuilder.setNodeRef(new NodeRef(nodeIId));
+        deviceMastershipManager.onNodeRemoved(nodeRemovedBuilder.build());
         Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
-        Mockito.verify(registration).close();
     }
 
     @Test
     public void testIsDeviceMasteredOrSlaved() {
         // no context
         Assert.assertFalse(deviceMastershipManager.isDeviceMastered(NODE_ID));
-        deviceMastershipManager.onDeviceConnected(NODE_ID);
+        NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+        nodeUpdatedBuilder.setId(NODE_ID);
+        deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
         // is master
         deviceMastershipManager.getDeviceMasterships().get(NODE_ID).instantiateServiceInstance();
         Assert.assertTrue(deviceMastershipManager.isDeviceMastered(NODE_ID));
index acada3752301bb3fb142bcb17a5b23d808f746f4..997c556f756b412a5e40e2427ba0e8e70eb4d5e8 100644 (file)
@@ -20,6 +20,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -63,6 +64,8 @@ public class FlowListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -70,7 +73,8 @@ public class FlowListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index e33a88d52aca9eb6ec7ea83342a8d3e3ea84f493..91f437c955a4bde97c7f71fae0064a37b601aca5 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -53,6 +54,8 @@ public class GroupListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -60,7 +63,8 @@ public class GroupListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index bab64fc88575015472ad3c50cd87936797447373..1afff7b91405f82da35a5d9596b07948becd4274 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -53,6 +54,8 @@ public class MeterListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -60,7 +63,8 @@ public class MeterListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index c0ee47212444c710ad5c9c0b2c717e5df19bca6d..4834f9f84037d24bb8892fbfd1f5e93cf4c10317 100644 (file)
@@ -16,6 +16,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
@@ -35,6 +36,8 @@ public class NodeListenerTest extends FRMTest {
     RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
     @Mock
     ClusterSingletonServiceProvider clusterSingletonService;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -42,7 +45,8 @@ public class NodeListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
     }
 
index 1dd9697173988dcd40e8888a004701514f5e33b8..1060e795bde9eb1268effc99027183eb3840d5b9 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -48,6 +49,8 @@ public class TableFeaturesListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -55,7 +58,8 @@ public class TableFeaturesListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index efd6fe4e7a3bf3d6c12da669f22c75e03ffecdac..2cab358cef6031e4095e812d5a126800b6f030b4 100644 (file)
@@ -147,5 +147,9 @@ public interface DeviceContext extends
     ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
 
     boolean canUseSingleLayerSerialization();
+
+    void sendNodeAddedNotification();
+
+    void sendNodeRemovedNotification();
 }
 
index 43db4f34ebbd0f86013051c59257626f9ef35894..59eb2b943a602be6f07b608fad6b8941eb396d00 100644 (file)
@@ -19,16 +19,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timeout;
 import io.netty.util.TimerTask;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
@@ -89,6 +79,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
@@ -119,6 +111,17 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
 public class DeviceContextImpl implements DeviceContext, ExtensionConverterProviderKeeper {
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceContextImpl.class);
@@ -166,6 +169,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     private final DeviceManager myManager;
     private final DeviceInitializerProvider deviceInitializerProvider;
     private final boolean useSingleLayerSerialization;
+    private Boolean isAddNotificationSent = false;
 
     DeviceContextImpl(
         @Nonnull final ConnectionContext primaryConnectionContext,
@@ -355,6 +359,26 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         }
     }
 
+    @Override
+    public void sendNodeAddedNotification() {
+        if (!isAddNotificationSent) {
+            isAddNotificationSent = true;
+            NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
+            builder.setId(getDeviceInfo().getNodeId());
+            builder.setNodeRef(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()));
+            LOG.debug("Publishing node added notification for {}", builder.build());
+            notificationPublishService.offerNotification(builder.build());
+        }
+    }
+
+    @Override
+    public void sendNodeRemovedNotification() {
+        NodeRemovedBuilder builder = new NodeRemovedBuilder();
+        builder.setNodeRef(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()));
+        LOG.debug("Publishing node removed notification for {}", builder.build());
+        notificationPublishService.offerNotification(builder.build());
+    }
+
     @Override
     public void processPortStatusMessage(final PortStatusMessage portStatus) {
         messageSpy.spyMessage(portStatus.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
@@ -595,6 +619,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
                     if (LOG.isDebugEnabled()) {
                         LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
                     }
+                    sendNodeAddedNotification();
                 }
 
                 @Override
@@ -641,6 +666,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         } else {
             this.state = CONTEXT_STATE.TERMINATION;
         }
+        sendNodeRemovedNotification();
     }
 
     @Override
@@ -776,6 +802,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Role MASTER was successfully set on device, node {}", deviceInfo.getLOGValue());
             }
+            sendNodeAddedNotification();
         }
 
         @Override
index df49b1443769a6145fa754673ab673114b22c2b1..9ace923392f8e6bc4b3ae4888a7f70becc8abbdd 100644 (file)
@@ -405,6 +405,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
                 }
+                deviceContext.sendNodeAddedNotification();
             }
 
             @Override