From 5ea4457df89af38b98553b5a9be824f25c545447 Mon Sep 17 00:00:00 2001 From: Jon Castro Date: Tue, 7 Feb 2017 10:35:13 +1100 Subject: [PATCH] Bug 7736 - Forwarding Rules application cluster singleton id should not use the same cluster singleton id as the openflow switch singleton connection handler Change-Id: Ie82b2d7d23444927375ed5b63f5e765f3277ed00 Signed-off-by: Jon Castro --- .../frm/impl/DeviceMastership.java | 13 ++-- .../frm/impl/DeviceMastershipManager.java | 62 ++++++++++++++++--- .../frm/impl/ForwardingRulesManagerImpl.java | 13 +++- .../blueprint/forwardingrules-manager.xml | 2 + .../frm/impl/DeviceMastershipManagerTest.java | 30 +++++++-- .../test/java/test/mock/FlowListenerTest.java | 6 +- .../java/test/mock/GroupListenerTest.java | 6 +- .../java/test/mock/MeterListenerTest.java | 6 +- .../test/java/test/mock/NodeListenerTest.java | 6 +- .../test/mock/TableFeaturesListenerTest.java | 6 +- .../api/openflow/device/DeviceContext.java | 4 ++ .../impl/device/DeviceContextImpl.java | 47 ++++++++++---- .../impl/device/DeviceManagerImpl.java | 1 + 13 files changed, 164 insertions(+), 38 deletions(-) diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java index 54360a005d..e6876ae401 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java @@ -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 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); + } } diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java index dd7c2721c7..2286338b07 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java @@ -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 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 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(); + } + } } diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java index 61665cb59b..093ed96782 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java @@ -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 diff --git a/applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml b/applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml index b6f154e065..c7d81bdc02 100644 --- a/applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml +++ b/applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml @@ -5,6 +5,7 @@ + + \ No newline at end of file diff --git a/applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java b/applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java index 870eb6be1b..31a83f605c 100644 --- a/applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java +++ b/applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java @@ -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.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 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)); diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java b/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java index acada37523..997c556f75 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java @@ -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); diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java b/applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java index e33a88d52a..91f437c955 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java @@ -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); diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java b/applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java index bab64fc885..1afff7b914 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java @@ -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); diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java b/applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java index c0ee472124..4834f9f840 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java @@ -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(); } diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java b/applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java index 1dd9697173..1060e795bd 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java @@ -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); diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java index b4e0b098fd..202abb6ef6 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java @@ -145,5 +145,9 @@ public interface DeviceContext extends * @return listenable future from sal role service */ ListenableFuture> makeDeviceSlave(); + + void sendNodeAddedNotification(); + + void sendNodeRemovedNotification(); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java index 302deb93e5..615cff865a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java @@ -19,17 +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.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -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; @@ -86,6 +75,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; @@ -117,6 +108,16 @@ 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.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); @@ -164,6 +165,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi private volatile CONTEXT_STATE state; private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler; private final DeviceManager myManager; + private Boolean isAddNotificationSent = false; DeviceContextImpl( @Nonnull final ConnectionContext primaryConnectionContext, @@ -346,6 +348,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); @@ -634,6 +656,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi if (LOG.isDebugEnabled()) { LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue()); } + sendNodeAddedNotification(); } @Override @@ -680,6 +703,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi } else { this.state = CONTEXT_STATE.TERMINATION; } + sendNodeRemovedNotification(); } @Override @@ -803,6 +827,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi if (LOG.isDebugEnabled()) { LOG.debug("Role MASTER was successfully set on device, node {}", deviceInfo.getLOGValue()); } + sendNodeAddedNotification(); } @Override diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java index d88cb1c359..a45511ec38 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java @@ -397,6 +397,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 -- 2.36.6