From: Anil Vishnoi Date: Sat, 11 Mar 2017 03:26:43 +0000 (+0000) Subject: Merge "Bug 6110: Fixed bugs in statistics manager due to race condition." into stable... X-Git-Tag: release/boron-sr3~6 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=d1af0fd5a4053a10917f631bae42970c1960fd20;hp=5ea63885f11c0b0a9af7f83ffa03f62ebc9c1b4f;p=openflowplugin.git Merge "Bug 6110: Fixed bugs in statistics manager due to race condition." into stable/boron --- 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/applications/lldp-speaker/src/main/resources/org/opendaylight/blueprint/lldp-speaker.xml b/applications/lldp-speaker/src/main/resources/org/opendaylight/blueprint/lldp-speaker.xml index ca8fa54dd9..d07cc2d1ee 100644 --- a/applications/lldp-speaker/src/main/resources/org/opendaylight/blueprint/lldp-speaker.xml +++ b/applications/lldp-speaker/src/main/resources/org/opendaylight/blueprint/lldp-speaker.xml @@ -14,7 +14,7 @@ ]]> - - \ No newline at end of file + diff --git a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommit.java b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommit.java index e6dfc888f9..740f82378c 100644 --- a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommit.java +++ b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommit.java @@ -10,10 +10,6 @@ package org.opendaylight.openflowplugin.applications.statistics.manager.impl; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; @@ -33,6 +29,12 @@ import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; + /** * statistics-manager * org.opendaylight.openflowplugin.applications.statistics.manager.impl @@ -52,10 +54,12 @@ public abstract class StatAbstractListenCommit, Map, Integer>> mapNodesForDelete = new ConcurrentHashMap<>(); protected final Map, Integer> mapNodeFeautureRepeater = new ConcurrentHashMap<>(); + protected final Map, ArrayList> removedDataBetweenStatsCycle = new + ConcurrentHashMap<>(); private final Class clazz; - private final DataBroker dataBroker; + protected final DataBroker dataBroker; protected final StatNodeRegistration nodeRegistrationManager; @@ -98,6 +102,8 @@ public abstract class StatAbstractListenCommit getWildCardedRegistrationPath(); + protected abstract void processDataChange(Collection> changes); + @Override public void onDataTreeChanged(Collection> changes) { Preconditions.checkNotNull(changes, "Changes must not be null!"); @@ -107,6 +113,7 @@ public abstract class StatAbstractListenCommit nodeIdent) { mapNodesForDelete.remove(nodeIdent); + removedDataBetweenStatsCycle.remove(nodeIdent); } @Override diff --git a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitFlow.java b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitFlow.java index 5e8fd252a6..49068c7161 100644 --- a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitFlow.java +++ b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitFlow.java @@ -11,16 +11,9 @@ package org.opendaylight.openflowplugin.applications.statistics.manager.impl; import com.google.common.base.Optional; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; @@ -57,6 +50,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.f import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; @@ -67,6 +61,18 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + /** * statistics-manager * org.opendaylight.openflowplugin.applications.statistics.manager.impl @@ -172,12 +178,30 @@ public class StatListenCommitFlow extends StatAbstractListenCommit> changes) { + if (!changes.isEmpty()) { + for (DataTreeModification dataChange : changes) { + if (dataChange.getRootNode().getModificationType() == DataObjectModification.ModificationType.DELETE) { + final InstanceIdentifier nodeIdent = dataChange.getRootPath().getRootIdentifier() + .firstIdentifierOf(Node.class); + if (!removedDataBetweenStatsCycle.containsKey(nodeIdent)) { + removedDataBetweenStatsCycle.put(nodeIdent, new ArrayList<>()); + } + Flow data = dataChange.getRootNode().getDataBefore(); + removedDataBetweenStatsCycle.get(nodeIdent).add(data); + LOG.debug("Node: {} :: Flow removed {}",nodeIdent.firstKeyOf(Node.class).getId(), data.toString()); + } + } + } + } + @Override public void onFlowsStatisticsUpdate(final FlowsStatisticsUpdate notification) { final TransactionId transId = notification.getTransactionId(); final NodeId nodeId = notification.getId(); if ( ! isExpectedStatistics(transId, nodeId)) { - LOG.debug("STAT-MANAGER - FlowsStatisticsUpdate: unregistred notification detect TransactionId {}", transId); + LOG.debug("STAT-MANAGER - FlowsStatisticsUpdate: unregistered notification detect TransactionId {}", + transId); return; } manager.getRpcMsgManager().addNotification(notification, nodeId); @@ -241,6 +265,15 @@ public class StatListenCommitFlow extends StatAbstractListenCommit fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class); + //cleanup the hashmap ID for the flows deleted between two stats cycle, also cleanup the + // data change cache as well. + ArrayList deletedFlows = removedDataBetweenStatsCycle.remove(nodeIdent); + + if (deletedFlows != null && !deletedFlows.isEmpty()) { + LOG.trace("Number of flows deleted from node {} between two stats cycles are {}", nodeIdent, deletedFlows + .size()); + } + final Optional fNode; try { fNode = tx.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet(); @@ -259,14 +292,39 @@ public class StatListenCommitFlow extends StatAbstractListenCommit deletedFlows) { + if (deletedFlows != null && !deletedFlows.isEmpty()) { + for (Flow flow : deletedFlows) { + final FlowAndStatisticsMapList configFlowStats = new FlowAndStatisticsMapListBuilder(flow).build(); + if ( flowStat.getMatch().equals(configFlowStats.getMatch()) && + flowStat.getPriority().equals(configFlowStats.getPriority()) && + flowStat.getCookie().equals(configFlowStats.getCookie()!=null?configFlowStats.getCookie(): + new FlowCookie(new BigInteger("0")))) { + LOG.debug("Flow statistics {} are related to flow {}, but it's REMOVED from the config data store" + + "store", flowStat, flow); + return flow; + } + } + } + return null; + } /** * Method adds statistics to Flow * @@ -346,12 +404,14 @@ public class StatListenCommitFlow extends StatAbstractListenCommit {}. Curr value: {} Equals:{}. Exception was raised:", + LOG.debug("Flow hashing hit a duplicate for {} -> {}. Curr value: {} Equals:{}. " + + "Exception was raised:", flowHashId.getKey(), flowHashId.getFlowId(), currData, flowHashId.getFlowId().equals(currData), e); } else { - LOG.warn("flow hashing hit a duplicate {}. Exception was raised: {}. Enable DEBUG for more detail.", + LOG.warn("Flow hashing hit a duplicate {}. Exception was raised: {}. Enable DEBUG for" + + " more detail.", flowHashId.getFlowId().toString().substring(0, Math.min(TRUNCATED_LOG_MESSAGE_LENGTH,flowHashId.getFlowId().toString().length())), e.getMessage().substring(0,Math.min(TRUNCATED_LOG_MESSAGE_LENGTH,e.getMessage().length()))); } @@ -401,10 +461,9 @@ public class StatListenCommitFlow extends StatAbstractListenCommit> changes) { + //NO-OP + } + @Override public void onGroupDescStatsUpdated(final GroupDescStatsUpdated notification) { final TransactionId transId = notification.getTransactionId(); diff --git a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitMeter.java b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitMeter.java index 20eb166586..58b57b7891 100644 --- a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitMeter.java +++ b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitMeter.java @@ -11,10 +11,12 @@ package org.opendaylight.openflowplugin.applications.statistics.manager.impl; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.UUID; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; @@ -83,6 +85,11 @@ public class StatListenCommitMeter extends StatAbstractListenCommit> changes) { + //NO-OP + } + @Override protected OpendaylightMeterStatisticsListener getStatNotificationListener() { return this; diff --git a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitQueue.java b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitQueue.java index db980dc1ee..cdfb8ced88 100644 --- a/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitQueue.java +++ b/applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitQueue.java @@ -10,6 +10,8 @@ package org.opendaylight.openflowplugin.applications.statistics.manager.impl; import com.google.common.base.Optional; import com.google.common.base.Preconditions; + +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -18,6 +20,7 @@ import java.util.Map.Entry; import java.util.UUID; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; @@ -84,6 +87,11 @@ public class StatListenCommitQueue extends StatAbstractListenCommit> changes) { + //NO-OP + } + @Override public void onQueueStatisticsUpdate(final QueueStatisticsUpdate notification) { final TransactionId transId = notification.getTransactionId(); diff --git a/applications/statistics-manager/src/test/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommitTest.java b/applications/statistics-manager/src/test/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommitTest.java index 122ffd0680..2eaac49f54 100644 --- a/applications/statistics-manager/src/test/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommitTest.java +++ b/applications/statistics-manager/src/test/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommitTest.java @@ -37,6 +37,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.NotificationListener; import java.util.ArrayList; +import java.util.Collection; /** @@ -77,6 +78,11 @@ public class StatAbstractListenCommitTest { return InstanceIdentifier.create(DataObject.class); } + @Override + protected void processDataChange(Collection changes) { + + } + @Override protected NotificationListener getStatNotificationListener() { return mockNotificationListener; diff --git a/extension/openflowplugin-extension-api/src/main/java/org/opendaylight/openflowplugin/extension/api/path/ActionPath.java b/extension/openflowplugin-extension-api/src/main/java/org/opendaylight/openflowplugin/extension/api/path/ActionPath.java index e299808943..056592a489 100644 --- a/extension/openflowplugin-extension-api/src/main/java/org/opendaylight/openflowplugin/extension/api/path/ActionPath.java +++ b/extension/openflowplugin-extension-api/src/main/java/org/opendaylight/openflowplugin/extension/api/path/ActionPath.java @@ -100,8 +100,42 @@ public enum ActionPath implements AugmentationPath { * | | +--ro (action)? * */ - GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION(null); - + GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION(null), + /** + * openflowplugin-extension-general.yang + *
+     * module: opendaylight-direct-statistics
+     * notifications:
+     *    +---n get-flow-statistics
+     *    |  +--ro flow-and-statistics-map-list* [flow-id]
+     *    |  |  +--ro instructions
+     *    |  |  |  +--ro instruction* [order]
+     *    |  |  |     +--ro (instruction)?
+     *    |  |  |        +--:(write-actions-case)
+     *    |  |  |        |  +--ro write-actions
+     *    |  |  |        |     +--ro action* [order]
+     *    |  |  |        |        +--ro (action)?
+     * 
+ */ + RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION(null), + /** + * openflowplugin-extension-general.yang + *
+     * module: opendaylight-direct-statistics
+     * notifications:
+     *    +---n get-flow-statistics
+     *    |  +--ro flow-and-statistics-map-list* [flow-id]
+     *    |  |  +--ro instructions
+     *    |  |  |  +--ro instruction* [order]
+     *    |  |  |     +--ro (instruction)?
+     *    |  |  |        +--:(apply-actions-case)
+     *    |  |  |        |  +--ro apply-actions
+     *    |  |  |        |     +--ro action* [order]
+     *    |  |  |        |        +--ro (action)?
+     * 
+ */ + RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION(null); + private final InstanceIdentifier iid; private ActionPath(InstanceIdentifier iid) { diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertor.java index 33fdde2509..8ee4ebe227 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionConntrackGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionConntrackNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrack; @@ -71,6 +73,10 @@ public class ConntrackConvertor implements return new NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxConntrack(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionConntrackNotifGroupDescStatsUpdatedCaseBuilder().setNxConntrack(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxConntrack(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxConntrack(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertor.java index 3c8a7e4248..92d9622514 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionFinTimeoutGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionFinTimeoutNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNodesNodeTableFlowWriteActionsCaseBuilder; @@ -59,6 +61,12 @@ public class FinTimeoutConvertor case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionFinTimeoutNotifGroupDescStatsUpdatedCaseBuilder() .setNxActionFinTimeout(nxActionFinTimeout).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCaseBuilder() + .setNxActionFinTimeout(nxActionFinTimeout).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCaseBuilder() + .setNxActionFinTimeout(nxActionFinTimeout).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/LearnConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/LearnConvertor.java index 9bc8f21ead..47ce802ea3 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/LearnConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/LearnConvertor.java @@ -20,6 +20,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionLearnGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionLearnNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionLearnNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionLearnNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionLearnNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionLearnNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionLearnNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.NxLearn; @@ -53,6 +55,10 @@ public class LearnConvertor implements return new NxActionLearnNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxLearn(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionLearnNotifGroupDescStatsUpdatedCaseBuilder().setNxLearn(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionLearnNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxLearn(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionLearnNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxLearn(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertor.java index 247946f9c8..cc7f8b7c1e 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionMultipathGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionMultipathNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath; @@ -74,6 +76,10 @@ public class MultipathConvertor implements return new NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxMultipath(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionMultipathNotifGroupDescStatsUpdatedCaseBuilder().setNxMultipath(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxMultipath(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxMultipath(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertor.java index 054b23b766..55f3f32c20 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionOutputRegGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionOutputRegNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg; @@ -60,6 +62,10 @@ public class OutputRegConvertor implements return new NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxOutputReg(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionOutputRegNotifGroupDescStatsUpdatedCaseBuilder().setNxOutputReg(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxOutputReg(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxOutputReg(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PopNshConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PopNshConvertor.java index 0480bd607e..1f5950a61c 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PopNshConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PopNshConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionPopNshGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPopNshNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPopNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionPopNshNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPopNshNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.pop.nsh.grouping.NxPopNsh; @@ -47,6 +49,10 @@ public class PopNshConvertor implements return new NxActionPopNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxPopNsh(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionPopNshNotifGroupDescStatsUpdatedCaseBuilder().setNxPopNsh(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionPopNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxPopNsh(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionPopNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxPopNsh(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PushNshConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PushNshConvertor.java index b8ac8934b2..83ae5ac912 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PushNshConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PushNshConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionPushNshGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPushNshNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPushNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionPushNshNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPushNshNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.push.nsh.grouping.NxPushNsh; @@ -47,6 +49,10 @@ public class PushNshConvertor implements return new NxActionPushNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxPushNsh(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionPushNshNotifGroupDescStatsUpdatedCaseBuilder().setNxPushNsh(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionPushNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxPushNsh(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionPushNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxPushNsh(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertor.java index 32766c46a0..d6ecfe12da 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertor.java @@ -20,6 +20,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionRegLoadGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegLoadNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad; @@ -74,6 +76,10 @@ public class RegLoadConvertor implements return new NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxRegLoad(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionRegLoadNotifGroupDescStatsUpdatedCaseBuilder().setNxRegLoad(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxRegLoad(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxRegLoad(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertor.java index 2dd71c9829..838271d15b 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertor.java @@ -85,6 +85,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfMplsLabelCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegMoveNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove; @@ -385,6 +387,10 @@ public class RegMoveConvertor implements return new NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxRegMove(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionRegMoveNotifGroupDescStatsUpdatedCaseBuilder().setNxRegMove(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxRegMove(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxRegMove(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertor.java index 49befee900..b27fac6270 100644 --- a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertor.java +++ b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertor.java @@ -21,6 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionResubmitGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateWriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionResubmitNotifGroupDescStatsUpdatedCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit; @@ -52,6 +54,10 @@ public class ResubmitConvertor implements return new NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxResubmit(value).build(); case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION: return new NxActionResubmitNotifGroupDescStatsUpdatedCaseBuilder().setNxResubmit(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION: + return new NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxResubmit(value).build(); + case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION: + return new NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxResubmit(value).build(); default: throw new CodecPreconditionException(path); } diff --git a/extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang b/extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang index a6b16c2197..4853a724d2 100644 --- a/extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang +++ b/extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang @@ -16,6 +16,7 @@ module openflowplugin-extension-nicira-action { import openflowplugin-extension-general {prefix ext-gen;revision-date "2014-07-14";} import openflow-action {prefix ofaction;revision-date "2015-02-03";} import nicira-action {prefix nicira-action;revision-date "2014-04-21";} + import opendaylight-direct-statistics {prefix directstat;revision-date "2016-05-11";} description "Nicira openflow action extensions."; @@ -1598,4 +1599,69 @@ bits specified from the register."; uses nx-action-learn-grouping; } } + augment "/directstat:get-flow-statistics/directstat:output/directstat:flow-and-statistics-map-list/directstat:instructions/directstat:instruction/directstat:instruction/directstat:apply-actions-case/directstat:apply-actions/directstat:action/directstat:action" { + case "nx-action-reg-load-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-reg-load-grouping; + } + case "nx-action-reg-move-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-reg-move-grouping; + } + case "nx-action-output-reg-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-output-reg-grouping; + } + case "nx-action-resubmit-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-resubmit-grouping; + } + case "nx-action-fin-timeout-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-fin-timeout-grouping; + } + case "nx-action-multipath-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-multipath-grouping; + } + case "nx-action-push-nsh-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-push-nsh-grouping; + } + case "nx-action-pop-nsh-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-pop-nsh-grouping; + } + case "nx-action-conntrack-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-conntrack-grouping; + } + case "nx-action-learn-notif-direct-statistics-update-apply-actions-case" { + uses nx-action-learn-grouping; + } + } + + augment "/directstat:get-flow-statistics/directstat:output/directstat:flow-and-statistics-map-list/directstat:instructions/directstat:instruction/directstat:instruction/directstat:write-actions-case/directstat:write-actions/directstat:action/directstat:action" { + case "nx-action-reg-load-notif-direct-statistics-update-write-actions-case" { + uses nx-action-reg-load-grouping; + } + case "nx-action-reg-move-notif-direct-statistics-update-write-actions-case" { + uses nx-action-reg-move-grouping; + } + case "nx-action-output-reg-notif-direct-statistics-update-write-actions-case" { + uses nx-action-output-reg-grouping; + } + case "nx-action-resubmit-notif-direct-statistics-update-write-actions-case" { + uses nx-action-resubmit-grouping; + } + case "nx-action-fin-timeout-notif-direct-statistics-update-write-actions-case" { + uses nx-action-fin-timeout-grouping; + } + case "nx-action-multipath-notif-direct-statistics-update-write-actions-case" { + uses nx-action-multipath-grouping; + } + case "nx-action-push-nsh-notif-direct-statistics-update-write-actions-case" { + uses nx-action-push-nsh-grouping; + } + case "nx-action-pop-nsh-notif-direct-statistics-update-write-actions-case" { + uses nx-action-pop-nsh-grouping; + } + case "nx-action-conntrack-notif-direct-statistics-update-write-actions-case" { + uses nx-action-conntrack-grouping; + } + case "nx-action-learn-notif-direct-statistics-update-write-actions-case" { + uses nx-action-learn-grouping; + } + } } diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertorTest.java index 0b4eb8a60d..db0ce97749 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertorTest.java @@ -19,6 +19,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.NxActionConntrackBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionConntrackNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder; @@ -86,6 +88,10 @@ public class ConntrackConvertorTest { = conntrackConvertor.convert(groupingAction, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action3 = conntrackConvertor.convert(groupingAction, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action4 + = conntrackConvertor.convert(groupingAction, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action5 + = conntrackConvertor.convert(groupingAction, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getConntrackZone().longValue()); Assert.assertEquals(1L, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getZoneSrc().longValue()); @@ -107,6 +113,14 @@ public class ConntrackConvertorTest { Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getRecircTable().intValue()); Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getFlags().intValue()); - } + Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getConntrackZone().longValue()); + Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getZoneSrc().longValue()); + Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getRecircTable().intValue()); + Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getFlags().intValue()); + Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getConntrackZone().longValue()); + Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getZoneSrc().longValue()); + Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getRecircTable().intValue()); + Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getFlags().intValue()); + } } \ No newline at end of file diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertorTest.java index 16571788d3..aa3bab2bf0 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertorTest.java @@ -23,6 +23,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.fin.timeout.grouping.NxActionFinTimeout; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionFinTimeoutNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNodesNodeTableFlowWriteActionsCase; @@ -81,6 +83,12 @@ public class FinTimeoutConvertorTest { final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 = finTimeoutConvertor.convert(action, ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 = + finTimeoutConvertor.convert(action, + ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 = + finTimeoutConvertor.convert(action, + ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); Assert.assertEquals(3, ((NxActionFinTimeoutNotifFlowsStatisticsUpdateApplyActionsCase) actionResult) .getNxActionFinTimeout().getFinIdleTimeout().intValue()); @@ -101,6 +109,15 @@ public class FinTimeoutConvertorTest { .getNxActionFinTimeout().getFinIdleTimeout().intValue()); Assert.assertEquals(4, ((NxActionFinTimeoutNodesNodeTableFlowWriteActionsCase) actionResult3) .getNxActionFinTimeout().getFinHardTimeout().intValue()); - } + Assert.assertEquals(3, ((NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCase) actionResult4) + .getNxActionFinTimeout().getFinIdleTimeout().intValue()); + Assert.assertEquals(4, ((NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCase) actionResult4) + .getNxActionFinTimeout().getFinHardTimeout().intValue()); + + Assert.assertEquals(3, ((NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCase) actionResult5) + .getNxActionFinTimeout().getFinIdleTimeout().intValue()); + Assert.assertEquals(4, ((NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCase) actionResult5) + .getNxActionFinTimeout().getFinHardTimeout().intValue()); + } } \ No newline at end of file diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertorTest.java index d7b74f972b..6018fff160 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertorTest.java @@ -27,6 +27,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNspCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionMultipathNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNodesNodeTableFlowWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath; @@ -101,6 +103,10 @@ public class MultipathConvertorTest { = multipathConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION); final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 = multipathConvertor.convert(action, ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 + = multipathConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 + = multipathConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); Assert.assertEquals(Integer.valueOf(1), ((NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxMultipath().getBasis()); Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxMultipath().getAlgorithm()); @@ -121,5 +127,15 @@ public class MultipathConvertorTest { Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNodesNodeTableFlowWriteActionsCase) actionResult3).getNxMultipath().getAlgorithm()); Assert.assertEquals(Long.valueOf(2L), ((NxActionMultipathNodesNodeTableFlowWriteActionsCase) actionResult3).getNxMultipath().getArg()); Assert.assertEquals(Integer.valueOf(2), ((NxActionMultipathNodesNodeTableFlowWriteActionsCase) actionResult3).getNxMultipath().getMaxLink()); + + Assert.assertEquals(Integer.valueOf(1), ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getBasis()); + Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getAlgorithm()); + Assert.assertEquals(Long.valueOf(2L), ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getArg()); + Assert.assertEquals(Integer.valueOf(2), ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getMaxLink()); + + Assert.assertEquals(Integer.valueOf(1), ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getBasis()); + Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getAlgorithm()); + Assert.assertEquals(Long.valueOf(2L), ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getArg()); + Assert.assertEquals(Integer.valueOf(2), ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getMaxLink()); } } \ No newline at end of file diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertorTest.java index 693f554b22..ced3776937 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertorTest.java @@ -24,6 +24,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.output.reg.grouping.NxActionOutputReg; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionOutputRegNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionOutputRegNodesNodeGroupBucketsBucketActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNodesNodeTableFlowWriteActionsCase; @@ -88,6 +90,10 @@ public class OutputRegConvertorTest { = outputRegConvertor.convert(action, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 = outputRegConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 + = outputRegConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 + = outputRegConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxOutputReg().getMaxLen()); Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxOutputReg().getSrc().getOfsNbits()); @@ -100,5 +106,12 @@ public class OutputRegConvertorTest { Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifGroupDescStatsUpdatedCase) actionResult3).getNxOutputReg().getMaxLen()); Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifGroupDescStatsUpdatedCase) actionResult3).getNxOutputReg().getSrc().getOfsNbits()); + + Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxOutputReg().getMaxLen()); + Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxOutputReg().getSrc().getOfsNbits()); + + Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxOutputReg().getMaxLen()); + Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxOutputReg().getSrc().getOfsNbits()); + } } \ No newline at end of file diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorTest.java index 789dcee0cc..7982d7a7a5 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorTest.java @@ -26,6 +26,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegLoadNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNodesNodeTableFlowWriteActionsCase; @@ -90,6 +92,10 @@ public class RegLoadConvertorTest { = regLoadConvertor.convert(action, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 = regLoadConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION); + org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 + = regLoadConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); + org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 + = regLoadConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); Assert.assertEquals(Integer.valueOf(0), ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getStart()); Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getEnd()); @@ -107,6 +113,14 @@ public class RegLoadConvertorTest { Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getDst().getEnd()); Assert.assertEquals(BigInteger.ONE, ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getValue()); + Assert.assertEquals(Integer.valueOf(0), ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst().getStart()); + Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst().getEnd()); + Assert.assertEquals(BigInteger.ONE, ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getValue()); + + Assert.assertEquals(Integer.valueOf(0), ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst().getStart()); + Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst().getEnd()); + Assert.assertEquals(BigInteger.ONE, ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getValue()); + } } \ No newline at end of file diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertorTest.java index 68bb84fb5a..b5b66113dc 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertorTest.java @@ -43,6 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfIpSrcCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegMoveNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNodesNodeTableFlowWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove; @@ -135,6 +137,10 @@ public class RegMoveConvertorTest { = regMoveConvertor.convert(action, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 = regMoveConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 + = regMoveConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 + = regMoveConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxRegMove().getDst().getStart()); Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxRegMove().getDst().getEnd()); @@ -144,6 +150,11 @@ public class RegMoveConvertorTest { Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegMove().getDst().getEnd()); Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegMove().getDst().getStart()); Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegMove().getDst().getEnd()); + Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegMove().getDst().getStart()); + Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegMove().getDst().getEnd()); + Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegMove().getDst().getStart()); + Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegMove().getDst().getEnd()); + } @Test diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertorTest.java index 8d142e35b6..a0ac194039 100644 --- a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertorTest.java +++ b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertorTest.java @@ -23,6 +23,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.resubmit.grouping.NxActionResubmit; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateWriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionResubmitNotifGroupDescStatsUpdatedCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit; @@ -79,6 +81,10 @@ public class ResubmitConvertorTest { = resubmitConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION); final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 = resubmitConvertor.convert(action, ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 + = resubmitConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION); + final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 + = resubmitConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION); Assert.assertEquals(3, ((NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxResubmit().getInPort().intValue()); Assert.assertEquals(4, ((NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxResubmit().getTable().intValue()); @@ -91,6 +97,11 @@ public class ResubmitConvertorTest { Assert.assertEquals(3, ((NxActionResubmitNodesNodeTableFlowWriteActionsCase) actionResult3).getNxResubmit().getInPort().intValue()); Assert.assertEquals(4, ((NxActionResubmitNodesNodeTableFlowWriteActionsCase) actionResult3).getNxResubmit().getTable().intValue()); - } + Assert.assertEquals(3, ((NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxResubmit().getInPort().intValue()); + Assert.assertEquals(4, ((NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxResubmit().getTable().intValue()); + + Assert.assertEquals(3, ((NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxResubmit().getInPort().intValue()); + Assert.assertEquals(4, ((NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxResubmit().getTable().intValue()); + } } \ No newline at end of file diff --git a/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang b/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang index 9de9cb7215..ad70cda601 100644 --- a/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang +++ b/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang @@ -122,15 +122,27 @@ module opendaylight-flow-types { bit SEND_FLOW_REM; } } + typedef removed-flow-reason { + type enumeration { + enum OFPRR_IDLE_TIMEOUT{ + value 0; + description "Flow idle time exceeded idle_timeout."; + } + enum OFPRR_HARD_TIMEOUT { + value 1; + description "Time exceeded hard_timeout."; + } + enum OFPRR_DELETE { + value 2; + description "Evicted by a DELETE flow mod."; + } + enum OFPRR_GROUP_DELETE { + value 3; + description "Group was removed."; + } - typedef removed_reason_flags { - type bits { - bit IDLE_TIMEOUT; - bit HARD_TIMEOUT; - bit DELETE; - bit GROUP_DELETE; - } - } + } + } grouping generic_flow_attributes { leaf priority { @@ -245,7 +257,7 @@ module opendaylight-flow-types { uses generic_flow_attributes; leaf removed_reason { - type removed_reason_flags; + type removed-flow-reason; } leaf duration_nsec { diff --git a/model/model-flow-service/src/main/yang/sal-flow.yang b/model/model-flow-service/src/main/yang/sal-flow.yang index 4cabb74ea5..2fe3c117ed 100644 --- a/model/model-flow-service/src/main/yang/sal-flow.yang +++ b/model/model-flow-service/src/main/yang/sal-flow.yang @@ -4,7 +4,7 @@ module sal-flow { import yang-ext {prefix ext; revision-date "2013-07-09";} import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} - import opendaylight-flow-types {prefix types;revision-date "2013-10-26";} + import opendaylight-flow-types {prefix types;revision-date "2013-10-26";} import opendaylight-group-types {prefix group-type;revision-date "2013-10-18";} import opendaylight-meter-types {prefix meter-type;revision-date "2013-09-18";} import flow-capable-transaction {prefix tr; revision-date "2015-03-04";} @@ -157,6 +157,9 @@ module sal-flow { leaf flow-ref { type types:flow-ref; } + leaf reason { + type types:removed-flow-reason; + } uses node-flow; uses tr:transaction-aware; } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java index bd05be9e44..5fcd1b9fa7 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java @@ -40,9 +40,8 @@ public interface OFPContext extends AutoCloseable, ClusterLifecycleSupervisor, C /** * About to stop services in cluster not master anymore or going down * @return Future most of services need time to be closed - * @param connectionInterrupted true if clustering services stopping by device disconnect */ - default ListenableFuture stopClusterServices(boolean connectionInterrupted) { + default ListenableFuture stopClusterServices() { return Futures.immediateFailedFuture(new RejectedExecutionException("Cannot stop abstract services, check implementation of cluster services")); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java index b42c9d1a5d..63830b4951 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java @@ -14,6 +14,7 @@ import org.opendaylight.controller.md.sal.binding.api.BindingService; 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.NotificationService; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; @@ -41,6 +42,9 @@ public interface OpenFlowPluginProvider extends AutoCloseable, BindingService { void setNotificationPublishService(NotificationPublishService notificationPublishService); + void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider); + + void setEntityOwnershipServiceProvider(EntityOwnershipService entityOwnershipService); /** * Method initializes all DeviceManager, RpcManager and related contexts. */ @@ -76,8 +80,6 @@ public interface OpenFlowPluginProvider extends AutoCloseable, BindingService { void update(Map props); - void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider); - void setSkipTableFeatures(boolean skipTableFeatures); void setBasicTimerDelay(long basicTimerDelay); 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..b5aa65fb61 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,11 @@ public interface DeviceContext extends * @return listenable future from sal role service */ ListenableFuture> makeDeviceSlave(); + + void sendNodeAddedNotification(); + + void sendNodeRemovedNotification(); + + void cleanupDeviceData(); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java index 9698c25515..d55908b211 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java @@ -9,6 +9,8 @@ package org.opendaylight.openflowplugin.api.openflow.device; import com.google.common.util.concurrent.CheckedFuture; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.openflowplugin.api.openflow.OFPManager; import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler; @@ -24,7 +26,8 @@ public interface DeviceManager extends OFPManager, DeviceConnectedHandler, DeviceDisconnectedHandler, - TranslatorLibrarian { + TranslatorLibrarian, + EntityOwnershipListener { /** * invoked after all services injected diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java index 931aaf0cc1..57608463db 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java @@ -9,6 +9,9 @@ package org.opendaylight.openflowplugin.api.openflow.lifecycle; import javax.annotation.CheckForNull; + +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.openflowplugin.api.openflow.OFPContext; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderFactoryImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderFactoryImpl.java index bc77011863..74944b00e6 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderFactoryImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderFactoryImpl.java @@ -48,11 +48,16 @@ public class OpenFlowPluginProviderFactoryImpl implements OpenFlowPluginProvider providerConfig.getThreadPoolMaxThreads().getValue(), providerConfig.getThreadPoolTimeout()); + //Set services openflowPluginProvider.setSwitchConnectionProviders(switchConnectionProviders); openflowPluginProvider.setDataBroker(dataBroker); openflowPluginProvider.setRpcProviderRegistry(rpcRegistry); openflowPluginProvider.setNotificationProviderService(notificationService); openflowPluginProvider.setNotificationPublishService(notificationPublishService); + openflowPluginProvider.setEntityOwnershipServiceProvider(entityOwnershipService); + openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider); + + //Set config parameters openflowPluginProvider.setSwitchFeaturesMandatory(providerConfig.isSwitchFeaturesMandatory()); openflowPluginProvider.setFlowRemovedNotification(providerConfig.isEnableFlowRemovedNotification()); openflowPluginProvider.setIsStatisticsRpcEnabled(providerConfig.isIsStatisticsRpcEnabled()); @@ -60,7 +65,6 @@ public class OpenFlowPluginProviderFactoryImpl implements OpenFlowPluginProvider openflowPluginProvider.setBarrierInterval(providerConfig.getBarrierIntervalTimeoutLimit().getValue()); openflowPluginProvider.setEchoReplyTimeout(providerConfig.getEchoReplyTimeout().getValue()); openflowPluginProvider.setStatisticsPollingOn(providerConfig.isIsStatisticsPollingOn()); - openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider); openflowPluginProvider.setSkipTableFeatures(providerConfig.isSkipTableFeatures()); openflowPluginProvider.setBasicTimerDelay(providerConfig.getBasicTimerDelay().getValue()); openflowPluginProvider.setMaximumTimerDelay(providerConfig.getMaximumTimerDelay().getValue()); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java index 08ccb34e23..b395354958 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java @@ -31,6 +31,7 @@ import javax.management.ObjectName; 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.NotificationService; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; @@ -86,6 +87,8 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF private ConnectionManager connectionManager; private NotificationService notificationProviderService; private NotificationPublishService notificationPublishService; + private EntityOwnershipService entityOwnershipService; + private ClusterSingletonServiceProvider singletonServicesProvider; private ExtensionConverterManager extensionConverterManager; private DataBroker dataBroker; private Collection switchConnectionProviders; @@ -98,7 +101,6 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF private long maximumTimerDelay; private final ThreadPoolExecutor threadPool; - private ClusterSingletonServiceProvider singletonServicesProvider; public OpenFlowPluginProviderImpl(final long rpcRequestsQuota, final long globalNotificationQuota, @@ -183,6 +185,11 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF this.singletonServicesProvider = singletonServicesProvider; } + @Override + public void setEntityOwnershipServiceProvider(EntityOwnershipService entityOwnershipService) { + this.entityOwnershipService = entityOwnershipService; + } + @Override public void setSkipTableFeatures(final boolean skipTableFeatures){ this.skipTableFeatures = skipTableFeatures; @@ -246,10 +253,11 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF getMessageIntelligenceAgency(), isFlowRemovedNotificationOn, singletonServicesProvider, - notificationPublishService, + entityOwnershipService, hashedWheelTimer, convertorManager, - skipTableFeatures); + skipTableFeatures, + notificationPublishService); ((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager); 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..f87bbaa810 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 @@ -12,6 +12,7 @@ import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Verify; import com.google.common.util.concurrent.AsyncFunction; +import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.JdkFutureAdapters; @@ -19,17 +20,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 +76,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 +109,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 +166,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, @@ -327,7 +330,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi final ItemLifecycleListener itemLifecycleListener = flowLifeCycleKeeper.getItemLifecycleListener(); if (itemLifecycleListener != null) { //2. create registry key - final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedNotification); + final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(getDeviceInfo().getVersion(), flowRemovedNotification); //3. lookup flowId final FlowDescriptor flowDescriptor = deviceFlowRegistry.retrieveIdForFlow(flowRegKey); //4. if flowId present: @@ -346,6 +349,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); @@ -614,51 +637,25 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi } @Override - public ListenableFuture stopClusterServices(boolean connectionInterrupted) { + public ListenableFuture stopClusterServices() { final ListenableFuture deactivateTxManagerFuture = initialized ? transactionChainManager.deactivateTransactionManager() : Futures.immediateFuture(null); + final boolean connectionInterrupted = + this.getPrimaryConnectionContext() + .getConnectionState() + .equals(ConnectionContext.CONNECTION_STATE.RIP); if (!connectionInterrupted) { - final ListenableFuture makeSlaveFuture = Futures.transform(makeDeviceSlave(), new Function, Void>() { - @Nullable - @Override - public Void apply(@Nullable RpcResult setRoleOutputRpcResult) { - return null; - } - }); - - Futures.addCallback(makeSlaveFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable Void aVoid) { - if (LOG.isDebugEnabled()) { - LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue()); - } - } - - @Override - public void onFailure(final Throwable throwable) { - LOG.warn("Was not able to set role SLAVE to device on node {} ", deviceInfo.getLOGValue()); - LOG.trace("Error occurred on device role setting, probably connection loss: ", throwable); - } - }); - - return Futures.transform(deactivateTxManagerFuture, new AsyncFunction() { - @Override - public ListenableFuture apply(Void aVoid) throws Exception { - // Add fallback to remove device from operational DS if setting slave fails - return Futures.withFallback(makeSlaveFuture, t -> - myManager.removeDeviceFromOperationalDS(deviceInfo)); - } - }); - } else { - return Futures.transform(deactivateTxManagerFuture, new AsyncFunction() { - @Override - public ListenableFuture apply(Void aVoid) throws Exception { - return myManager.removeDeviceFromOperationalDS(deviceInfo); - } - }); + LOG.info("This controller instance is now acting as a non-owner for node {}", deviceInfo.getLOGValue()); } + + return deactivateTxManagerFuture; + } + + @Override + public void cleanupDeviceData() { + myManager.removeDeviceFromOperationalDS(deviceInfo); } @Override @@ -680,6 +677,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi } else { this.state = CONTEXT_STATE.TERMINATION; } + sendNodeRemovedNotification(); } @Override @@ -745,7 +743,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi LOG.debug("Transaction chain manager for node {} created", deviceInfo.getLOGValue()); } this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo); - this.deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, deviceInfo.getNodeInstanceIdentifier()); + this.deviceFlowRegistry = new DeviceFlowRegistryImpl(deviceInfo.getVersion(), dataBroker, deviceInfo.getNodeInstanceIdentifier()); this.deviceGroupRegistry = new DeviceGroupRegistryImpl(); this.deviceMeterRegistry = new DeviceMeterRegistryImpl(); this.initialized = true; @@ -803,6 +801,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..3595e6af94 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 @@ -9,6 +9,7 @@ package org.opendaylight.openflowplugin.impl.device; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.base.Verify; import com.google.common.collect.Iterators; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; @@ -31,6 +32,9 @@ 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.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; @@ -54,13 +58,18 @@ import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl; import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl; import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl; +import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder; 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.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,9 +79,11 @@ import org.slf4j.LoggerFactory; public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProviderKeeper { private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class); + private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType"; private final long globalNotificationQuota; private final boolean switchFeaturesMandatory; + private final EntityOwnershipListenerRegistration eosListenerRegistration; private boolean isFlowRemovedNotificationOn; private boolean skipTableFeatures; private static final int SPY_RATE = 10; @@ -84,6 +95,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi private DeviceTerminationPhaseHandler deviceTerminPhaseHandler; private final ConcurrentMap deviceContexts = new ConcurrentHashMap<>(); + private final ConcurrentMap removeddeviceContexts = new ConcurrentHashMap<>(); private final ConcurrentMap lifecycleServices = new ConcurrentHashMap<>(); private long barrierIntervalNanos; @@ -92,6 +104,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi private ExtensionConverterProvider extensionConverterProvider; private ScheduledThreadPoolExecutor spyPool; private final ClusterSingletonServiceProvider singletonServiceProvider; + private final EntityOwnershipService entityOwnershipService; private final NotificationPublishService notificationPublishService; private final MessageSpy messageSpy; private final HashedWheelTimer hashedWheelTimer; @@ -104,25 +117,15 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi final MessageSpy messageSpy, final boolean isFlowRemovedNotificationOn, final ClusterSingletonServiceProvider singletonServiceProvider, - final NotificationPublishService notificationPublishService, + final EntityOwnershipService entityOwnershipService, final HashedWheelTimer hashedWheelTimer, final ConvertorExecutor convertorExecutor, - final boolean skipTableFeatures) { + final boolean skipTableFeatures, + final NotificationPublishService notificationPublishService) { - this.dataBroker = dataBroker; - - /* merge empty nodes to oper DS to predict any problems with missing parent for Node */ - final WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); - final NodesBuilder nodesBuilder = new NodesBuilder(); - nodesBuilder.setNode(Collections.emptyList()); - tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodesBuilder.build()); - try { - tx.submit().get(); - } catch (ExecutionException | InterruptedException e) { - LOG.error("Creation of node failed.", e); - throw new IllegalStateException(e); - } + this.dataBroker = dataBroker; + this.entityOwnershipService = entityOwnershipService; this.switchFeaturesMandatory = switchFeaturesMandatory; this.globalNotificationQuota = globalNotificationQuota; this.isFlowRemovedNotificationOn = isFlowRemovedNotificationOn; @@ -135,6 +138,21 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi this.singletonServiceProvider = singletonServiceProvider; this.notificationPublishService = notificationPublishService; this.messageSpy = messageSpy; + + this.eosListenerRegistration = Verify.verifyNotNull(entityOwnershipService.registerListener + (SERVICE_ENTITY_TYPE, this)); + + /* merge empty nodes to oper DS to predict any problems with missing parent for Node */ + final WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); + final NodesBuilder nodesBuilder = new NodesBuilder(); + nodesBuilder.setNode(Collections.emptyList()); + tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodesBuilder.build()); + try { + tx.submit().get(); + } catch (ExecutionException | InterruptedException e) { + LOG.error("Creation of node failed.", e); + throw new IllegalStateException(e); + } } @@ -254,6 +272,15 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi Optional.ofNullable(spyPool).ifPresent(ScheduledThreadPoolExecutor::shutdownNow); spyPool = null; + if (Objects.nonNull(eosListenerRegistration)) { + try { + LOG.debug("Closing entity ownership listener"); + eosListenerRegistration.close(); + } catch (Exception e) { + LOG.debug("Failed to close entity ownership listener registration with exception",e); + } + } + } @Override @@ -368,28 +395,34 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi @Override public CheckedFuture removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) { + return removeDeviceFromOperationalDS(deviceInfo.getNodeInstanceIdentifier(), deviceInfo.getLOGValue()); + } + + private CheckedFuture removeDeviceFromOperationalDS( + final KeyedInstanceIdentifier nodeIid, final String nodeName) { + Preconditions.checkNotNull(nodeIid, "Node IID must not be null"); + final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction(); - delWtx.delete(LogicalDatastoreType.OPERATIONAL, deviceInfo.getNodeInstanceIdentifier()); + delWtx.delete(LogicalDatastoreType.OPERATIONAL, nodeIid); final CheckedFuture delFuture = delWtx.submit(); Futures.addCallback(delFuture, new FutureCallback() { @Override public void onSuccess(final Void result) { if (LOG.isDebugEnabled()) { - LOG.debug("Delete Node {} was successful", deviceInfo.getLOGValue()); + LOG.debug("Delete Node {} was successful", nodeName); } } @Override public void onFailure(@Nonnull final Throwable t) { - LOG.warn("Delete node {} failed with exception {}", deviceInfo.getLOGValue(), t); + LOG.warn("Delete node {} failed with exception {}", nodeName, t); } }); return delFuture; } - private void addCallbackToDeviceInitializeToSlave(final DeviceInfo deviceInfo, final DeviceContext deviceContext, final LifecycleService lifecycleService) { Futures.addCallback(deviceContext.makeDeviceSlave(), new FutureCallback>() { @Override @@ -397,6 +430,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 @@ -426,10 +460,38 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi } public void onDeviceRemoved(DeviceInfo deviceInfo) { - deviceContexts.remove(deviceInfo); + DeviceContext deviceContext = deviceContexts.remove(deviceInfo); + removeddeviceContexts.putIfAbsent(deviceInfo, deviceContext); LOG.debug("Device context removed for node {}", deviceInfo.getLOGValue()); lifecycleServices.remove(deviceInfo); LOG.debug("Lifecycle service removed for node {}", deviceInfo.getLOGValue()); } + + @Override + public void ownershipChanged(EntityOwnershipChange entityOwnershipChange) { + if (!entityOwnershipChange.hasOwner()) { + final YangInstanceIdentifier yii = entityOwnershipChange.getEntity().getId(); + final YangInstanceIdentifier.NodeIdentifierWithPredicates niiwp = + (YangInstanceIdentifier.NodeIdentifierWithPredicates) yii.getLastPathArgument(); + String entityName = niiwp.getKeyValues().values().iterator().next().toString(); + LOG.info("Entity ownership changed for device : {} : {}", entityName, entityOwnershipChange); + + if (entityName != null ){ + if (!removeddeviceContexts.isEmpty()) { + for (DeviceInfo device : removeddeviceContexts.keySet()) { + if (device.getNodeId().getValue().equals(entityName)) { + LOG.info("Cleaning up operational data of the node : {}", entityName); + // No owner present for the entity, clean up the data and remove it from + // removed context. + removeddeviceContexts.remove(device).cleanupDeviceData(); + return; + } + } + } + removeDeviceFromOperationalDS(DeviceStateUtil.createNodeInstanceIdentifier(new NodeId(entityName)), + entityName); + } + } + } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java index 7522fe54b0..c4ac4c7d63 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java @@ -18,6 +18,7 @@ import java.util.Collection; import java.util.List; import java.util.Objects; import javax.annotation.Nullable; + import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; @@ -35,15 +36,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LifecycleServiceImpl implements LifecycleService { - private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class); + + private final List deviceRemovedHandlers = new ArrayList<>(); + private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION; private DeviceContext deviceContext; private RpcContext rpcContext; private StatisticsContext statContext; private ClusterSingletonServiceRegistration registration; private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler; - private final List deviceRemovedHandlers = new ArrayList<>(); - private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION; @Override @@ -57,17 +58,12 @@ public class LifecycleServiceImpl implements LifecycleService { @Override public ListenableFuture closeServiceInstance() { - final boolean connectionInterrupted = - this.deviceContext - .getPrimaryConnectionContext() - .getConnectionState() - .equals(ConnectionContext.CONNECTION_STATE.RIP); // Chain all jobs that will stop our services final List> futureList = new ArrayList<>(); - futureList.add(statContext.stopClusterServices(connectionInterrupted)); - futureList.add(rpcContext.stopClusterServices(connectionInterrupted)); - futureList.add(deviceContext.stopClusterServices(connectionInterrupted)); + futureList.add(statContext.stopClusterServices()); + futureList.add(rpcContext.stopClusterServices()); + futureList.add(deviceContext.stopClusterServices()); return Futures.transform(Futures.successfulAsList(futureList), new Function, Void>() { @Nullable @@ -114,10 +110,10 @@ public class LifecycleServiceImpl implements LifecycleService { // If we are still registered and we are not already closing, then close the registration if (Objects.nonNull(registration)) { try { - LOG.debug("Closing clustering MASTER services for node {}", getDeviceInfo().getLOGValue()); + LOG.debug("Closing clustering singleton services for node {}", getDeviceInfo().getLOGValue()); registration.close(); } catch (Exception e) { - LOG.debug("Failed to close clustering MASTER services for node {} with exception: ", + LOG.debug("Failed to close clustering singleton services for node {} with exception: ", getDeviceInfo().getLOGValue(), e); } } @@ -126,7 +122,7 @@ public class LifecycleServiceImpl implements LifecycleService { @Override public void registerService(final ClusterSingletonServiceProvider singletonServiceProvider) { - LOG.debug("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue()); + LOG.debug("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue()); // lifecycle service -> device context -> statistics context -> rpc context -> role context -> lifecycle service this.clusterInitializationPhaseHandler = deviceContext; @@ -139,7 +135,7 @@ public class LifecycleServiceImpl implements LifecycleService { // Register cluster singleton service try { this.registration = Verify.verifyNotNull(singletonServiceProvider.registerClusterSingletonService(this)); - LOG.info("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue()); + LOG.info("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue()); } catch (Exception e) { LOG.warn("Failed to register cluster singleton service for node {}, with exception: {}", getDeviceInfo(), e); closeConnection(); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImpl.java index 01f7178e2f..4115e8b5aa 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImpl.java @@ -51,23 +51,24 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry { private final DataBroker dataBroker; private final KeyedInstanceIdentifier instanceIdentifier; private final List>>> lastFillFutures = new ArrayList<>(); + private final Consumer flowConsumer; - // Specifies what to do with flow read from datastore - private final Consumer flowConsumer = flow -> { - // Create flow registry key from flow - final FlowRegistryKey key = FlowRegistryKeyFactory.create(flow); - - // Now, we will update the registry, but we will also try to prevent duplicate entries - if (!flowRegistry.containsKey(key)) { - LOG.trace("Found flow with table ID : {} and flow ID : {}", flow.getTableId(), flow.getId().getValue()); - final FlowDescriptor descriptor = FlowDescriptorFactory.create(flow.getTableId(), flow.getId()); - store(key, descriptor); - } - }; - - public DeviceFlowRegistryImpl(final DataBroker dataBroker, final KeyedInstanceIdentifier instanceIdentifier) { + public DeviceFlowRegistryImpl(final short version, final DataBroker dataBroker, final KeyedInstanceIdentifier instanceIdentifier) { this.dataBroker = dataBroker; this.instanceIdentifier = instanceIdentifier; + + // Specifies what to do with flow read from datastore + flowConsumer = flow -> { + // Create flow registry key from flow + final FlowRegistryKey key = FlowRegistryKeyFactory.create(version, flow); + + // Now, we will update the registry, but we will also try to prevent duplicate entries + if (!flowRegistry.containsKey(key)) { + LOG.trace("Found flow with table ID : {} and flow ID : {}", flow.getTableId(), flow.getId().getValue()); + final FlowDescriptor descriptor = FlowDescriptorFactory.create(flow.getTableId(), flow.getId()); + store(key, descriptor); + } + }; } @Override @@ -152,7 +153,7 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry { LOG.trace("Failed to retrieve flow descriptor for flow hash : {}, trying with custom equals method", flowRegistryKey.hashCode()); } for(Map.Entry fd : flowRegistry.entrySet()) { - if (fd.getKey().equals(flowRegistryKey)) { + if (flowRegistryKey.equals(fd.getKey())) { flowDescriptor = fd.getValue(); break; } @@ -235,4 +236,4 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry { final String alienId = ALIEN_SYSTEM_FLOW_ID + tableId + '-' + UNACCOUNTED_FLOWS_COUNTER.incrementAndGet(); return new FlowId(alienId); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactory.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactory.java index 889e30a2c2..a691b60ba2 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactory.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactory.java @@ -27,8 +27,8 @@ public class FlowRegistryKeyFactory { // Hide implicit constructor } - public static FlowRegistryKey create(final Flow flow) { - return new FlowRegistryKeyDto(flow); + public static FlowRegistryKey create(final short version, final Flow flow) { + return new FlowRegistryKeyDto(version, flow); } private static final class FlowRegistryKeyDto implements FlowRegistryKey { @@ -36,13 +36,15 @@ public class FlowRegistryKeyFactory { private final int priority; private final BigInteger cookie; private final Match match; + private final short version; - private FlowRegistryKeyDto(final Flow flow) { + private FlowRegistryKeyDto(final short version, final Flow flow) { //TODO: mandatory flow input values (or default values) should be specified via yang model tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null"); priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY); match = MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH); cookie = MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue(); + this.version = version; } @Override @@ -60,7 +62,7 @@ public class FlowRegistryKeyFactory { return getPriority() == that.getPriority() && getTableId() == that.getTableId() && getCookie().equals(that.getCookie()) && - MatchComparatorFactory.createMatch().areObjectsEqual(getMatch(), that.getMatch()); + MatchComparatorFactory.createMatch().areObjectsEqual(version, getMatch(), that.getMatch()); } @Override diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java index 6953784a3f..f794d85051 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java @@ -115,7 +115,7 @@ class RpcContextImpl implements RpcContext { } } else { try { - stopClusterServices(true).get(); + stopClusterServices().get(); } catch (Exception e) { LOG.debug("Failed to close RpcContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e); } @@ -188,7 +188,7 @@ class RpcContextImpl implements RpcContext { } @Override - public ListenableFuture stopClusterServices(boolean connectionInterrupted) { + public ListenableFuture stopClusterServices() { if (CONTEXT_STATE.TERMINATION.equals(getState())) { return Futures.immediateCancelledFuture(); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java index 9b1c0e7291..da8d74275d 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java @@ -7,11 +7,7 @@ */ package org.opendaylight.openflowplugin.impl.services; -import com.google.common.base.Function; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import java.util.Collections; -import java.util.List; +import com.google.common.base.Optional; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; @@ -22,6 +18,7 @@ import org.opendaylight.openflowplugin.impl.statistics.SinglePurposeMultipartRep import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; @@ -33,16 +30,21 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback> { private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestOnTheFlyCallback.class); private final SinglePurposeMultipartReplyTranslator multipartReplyTranslator; private final DeviceInfo deviceInfo; private final DeviceFlowRegistry registry; - private boolean virgin = true; - private boolean finished = false; private final EventIdentifier doneEventIdentifier; private final TxFacade txFacade; + private Optional fcNodeOpt; + private AtomicBoolean virgin = new AtomicBoolean(true); + private AtomicBoolean finished = new AtomicBoolean(false); public MultipartRequestOnTheFlyCallback(final RequestContext> context, final Class requestType, @@ -70,64 +72,57 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback> rpcResultBuilder = - RpcResultBuilder.>failed().withError(RpcError.ErrorType.APPLICATION, - String.format("Unexpected response type received %s.", result.getClass())); - setResult(rpcResultBuilder.build()); - endCollecting(); + if(!finished.getAndSet(true)) { + LOG.info("Unexpected response type received {}.", result.getClass()); + final RpcResultBuilder> rpcResultBuilder = + RpcResultBuilder.>failed().withError(RpcError.ErrorType.APPLICATION, + String.format("Unexpected response type received %s.", result.getClass())); + setResult(rpcResultBuilder.build()); + endCollecting(); + } } else { final MultipartReply multipartReply = (MultipartReply) result; + if (virgin.get()) { + synchronized (this) { + if (virgin.get()) { + fcNodeOpt = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, txFacade); + virgin.set(false); + } + } + } final MultipartReply singleReply = multipartReply; final List multipartDataList = multipartReplyTranslator.translate( deviceInfo.getDatapathId(), deviceInfo.getVersion(), singleReply); - final Iterable allMultipartData = multipartDataList; + final Iterable allMultipartData = (Iterable) multipartDataList; - //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats - ListenableFuture future; - if (virgin) { - future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade); - virgin = false; - } else { - future = Futures.immediateFuture(null); + StatisticsGatheringUtils.writeFlowStatistics(allMultipartData, deviceInfo, registry, txFacade); + if (!multipartReply.getFlags().isOFPMPFREQMORE()) { + endCollecting(); } - - Futures.transform(future, new Function() { - - @Override - public Void apply(final Void input) { - StatisticsGatheringUtils.writeFlowStatistics((Iterable) allMultipartData, - deviceInfo, registry, txFacade); - - if (!multipartReply.getFlags().isOFPMPFREQMORE()) { - endCollecting(); - } - return input; - } - }); } } private void endCollecting() { + finished.set(true); EventsTimeCounter.markEnd(getDoneEventIdentifier()); EventsTimeCounter.markEnd(getEventIdentifier()); final RpcResult> rpcResult = RpcResultBuilder.success(Collections.emptyList()).build(); spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS); - txFacade.submitTransaction(); setResult(rpcResult); - finished = true; + txFacade.submitTransaction(); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java index 5f032a7043..5a4ed71f75 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java @@ -75,7 +75,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { @Override public Future> addFlow(final AddFlowInput input) { - final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input); + final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input); final ListenableFuture> future = flowAdd.processFlowModInputBuilders(flowAdd.toFlowModInputs(input)); Futures.addCallback(future, new AddFlowCallback(input, flowRegistryKey)); @@ -187,7 +187,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { if (LOG.isDebugEnabled()) { LOG.debug("Flow remove finished without error for flow={}", input); } - FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input); + FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input); deviceContext.getDeviceFlowRegistry().removeDescriptor(flowRegistryKey); if (itemLifecycleListener != null) { @@ -226,8 +226,8 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { final UpdatedFlow updated = input.getUpdatedFlow(); final OriginalFlow original = input.getOriginalFlow(); - final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(original); - final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(updated); + final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), original); + final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), updated); final FlowDescriptor origFlowDescriptor = deviceFlowRegistry.retrieveIdForFlow(origFlowRegistryKey); final boolean isUpdate = Objects.nonNull(origFlowDescriptor); @@ -263,4 +263,4 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { LOG.warn("Service call for updating flow={} failed, reason: {}", input, throwable); } } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java index eab57c2795..3002b8e632 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java @@ -30,6 +30,7 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; import org.opendaylight.mdsal.common.api.TransactionChainClosedException; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.openflowplugin.api.ConnectionException; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; @@ -233,7 +234,7 @@ class StatisticsContextImpl implements StatisticsContext { } } else { try { - stopClusterServices(true).get(); + stopClusterServices().get(); } catch (Exception e) { LOG.debug("Failed to close StatisticsContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e); } @@ -276,7 +277,7 @@ class StatisticsContextImpl implements StatisticsContext { final String errMsg = String.format("Device connection is closed for Node : %s.", getDeviceInfo().getNodeId()); LOG.debug(errMsg); - resultFuture.setException(new IllegalStateException(errMsg)); + resultFuture.setException(new ConnectionException(errMsg)); return; } if ( ! iterator.hasNext()) { @@ -439,7 +440,7 @@ class StatisticsContextImpl implements StatisticsContext { } @Override - public ListenableFuture stopClusterServices(boolean connectionInterrupted) { + public ListenableFuture stopClusterServices() { if (CONTEXT_STATE.TERMINATION.equals(getState())) { return Futures.immediateCancelledFuture(); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java index 3893b9f391..bb789b6271 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java @@ -16,11 +16,6 @@ import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.JdkFutureAdapters; import com.google.common.util.concurrent.ListenableFuture; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import javax.annotation.Nullable; 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; @@ -111,6 +106,13 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; + /** * Utils for gathering statistics. */ @@ -314,8 +316,7 @@ public final class StatisticsGatheringUtils { final boolean initial, final EventIdentifier eventIdentifier) { final ListenableFuture deleteFuture - = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo, - flowRegistry, txFacade); + = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo, flowRegistry, txFacade); return Futures.transform(deleteFuture, (Function) input -> { writeFlowStatistics(data, deviceInfo, flowRegistry, txFacade); txFacade.submitTransaction(); @@ -333,12 +334,11 @@ public final class StatisticsGatheringUtils { for (final FlowsStatisticsUpdate flowsStatistics : data) { for (final FlowAndStatisticsMapList flowStat : flowsStatistics.getFlowAndStatisticsMapList()) { final FlowBuilder flowBuilder = new FlowBuilder(flowStat); - flowBuilder.addAugmentation( - FlowStatisticsData.class, + flowBuilder.addAugmentation(FlowStatisticsData.class, refineFlowStatisticsAugmentation(flowStat).build()); final short tableId = flowStat.getTableId(); - final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build()); + final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowBuilder.build()); final FlowId flowId = registry.storeIfNecessary(flowRegistryKey); final FlowKey flowKey = new FlowKey(flowId); @@ -350,7 +350,7 @@ public final class StatisticsGatheringUtils { } } } catch (TransactionChainClosedException e) { - LOG.warn("Not able to write to transaction: {}", e.getMessage()); + LOG.warn("Not able to write to transaction chain: {}", e.getMessage()); } } @@ -387,17 +387,45 @@ public final class StatisticsGatheringUtils { */ return Futures.transform( flowCapableNodeFuture, (AsyncFunction, Void>) flowCapNodeOpt -> { - if (flowCapNodeOpt.isPresent()) { - for (final Table tableData : flowCapNodeOpt.get().getTable()) { - final Table table = new TableBuilder(tableData).setFlow(Collections.emptyList()).build(); - final InstanceIdentifier iiToTable - = flowCapableNodePath.child(Table.class, tableData.getKey()); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table); + if (flowCapNodeOpt.isPresent()) { + for (final Table tableData : flowCapNodeOpt.get().getTable()) { + final Table table = new TableBuilder(tableData).setFlow(Collections.emptyList()).build(); + final InstanceIdentifier
iiToTable + = flowCapableNodePath.child(Table.class, tableData.getKey()); + txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table); + } } + readTx.close(); + return Futures.immediateFuture(null); + }); + } + + public static Optional deleteAllKnownFlows(final DeviceInfo deviceInfo, + final TxFacade txFacade) { + final InstanceIdentifier flowCapableNodePath + = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); + final ReadOnlyTransaction readTx = txFacade.getReadTransaction(); + final CheckedFuture, ReadFailedException> flowCapableNodeFuture = readTx.read( + LogicalDatastoreType.OPERATIONAL, flowCapableNodePath); + + try { + Optional fcNodeOpt = flowCapableNodeFuture.get(); + if ( fcNodeOpt != null && fcNodeOpt.isPresent()){ + for (final Table tableData : flowCapableNodeFuture.get().get().getTable()) { + final Table table = new TableBuilder(tableData).setFlow(Collections.emptyList()).build(); + final InstanceIdentifier
iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey()); + txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table); } + return fcNodeOpt; + } + } catch (InterruptedException|ExecutionException e) { + LOG.error("Failed to read current OpenFlow node {] operational data", deviceInfo.getNodeId()); + } finally { + if (readTx != null){ readTx.close(); - return Futures.immediateFuture(null); - }); + } + } + return Optional.absent(); } private static void processQueueStatistics( diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java index 35a0d73778..06dc64de26 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java @@ -21,6 +21,7 @@ import io.netty.util.TimerTask; import java.util.Iterator; import java.util.Map; import java.util.Optional; +import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Future; @@ -29,6 +30,7 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.openflowplugin.api.ConnectionException; import org.opendaylight.openflowplugin.api.openflow.OFPContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; @@ -155,9 +157,18 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag LOG.trace("Gathering for node {} failure: ", deviceInfo.getLOGValue(), throwable); } calculateTimerDelay(timeCounter); - if (throwable instanceof IllegalStateException) { + if (throwable instanceof ConnectionException) { + // ConnectionException is raised by StatisticsContextImpl class when the connections + // move to RIP state. In this particular case, there is no need to reschedule + // because this statistics manager should be closed soon + LOG.warn("Node {} is no more connected, stopping the statistics collection", + deviceInfo.getLOGValue(),throwable); stopScheduling(deviceInfo); } else { + if (!(throwable instanceof CancellationException)) { + LOG.warn("Unexpected error occurred during statistics collection for node {}, rescheduling " + + "statistics collections", deviceInfo.getLOGValue(),throwable); + } scheduleNextPolling(deviceState, deviceInfo, statisticsContext, timeCounter); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java index adbd1e9736..a106ad93e5 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java @@ -167,7 +167,7 @@ public class FlowDirectStatisticsService extends AbstractDirectStatisticsService final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics) .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build()); - final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build()); + final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build()); return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslator.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslator.java index eb9ff12296..86d4c9c3a4 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslator.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslator.java @@ -7,6 +7,7 @@ */ package org.opendaylight.openflowplugin.impl.translator; +import java.util.Objects; import java.util.Optional; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator; @@ -14,16 +15,19 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorE import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedFlowReason; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * translate {@link FlowRemoved} message to FlowRemoved notification (omit instructions) */ public class FlowRemovedTranslator implements MessageTranslator { private final ConvertorExecutor convertorExecutor; - + private static final Logger logger = LoggerFactory.getLogger(FlowRemovedTranslator.class); public FlowRemovedTranslator(ConvertorExecutor convertorExecutor) { this.convertorExecutor = convertorExecutor; } @@ -41,6 +45,10 @@ public class FlowRemovedTranslator implements MessageTranslator createInPort() { return new SimpleComparator() { /** * Comparation by InPort */ @Override - public boolean areObjectsEqual(Match statsMatch, Match storedMatch) { + public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) { if (storedMatch == null) { return false; } @@ -219,7 +247,7 @@ public final class MatchComparatorFactory { if (statsMatch.getInPort() != null) { return false; } - } else if (!storedMatch.getInPort().equals(statsMatch.getInPort())) { + } else if (!arePortNumbersEqual(version, storedMatch.getInPort(), statsMatch.getInPort())) { return false; } return true; @@ -233,7 +261,7 @@ public final class MatchComparatorFactory { * Comparation by InPhyPort */ @Override - public boolean areObjectsEqual(Match statsMatch, Match storedMatch) { + public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) { if (storedMatch == null) { return false; } @@ -241,7 +269,7 @@ public final class MatchComparatorFactory { if (statsMatch.getInPhyPort() != null) { return false; } - } else if (!storedMatch.getInPhyPort().equals(statsMatch.getInPhyPort())) { + } else if (!arePortNumbersEqual(version, storedMatch.getInPhyPort(), statsMatch.getInPhyPort())) { return false; } return true; @@ -255,7 +283,7 @@ public final class MatchComparatorFactory { * Comparation by Ethernet */ @Override - public boolean areObjectsEqual(Match statsMatch, Match storedMatch) { + public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) { if (storedMatch == null) { return false; } @@ -277,7 +305,7 @@ public final class MatchComparatorFactory { * Comparation by Icmpv4 */ @Override - public boolean areObjectsEqual(Match statsMatch, Match storedMatch) { + public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) { if (storedMatch == null) { return false; } @@ -299,12 +327,12 @@ public final class MatchComparatorFactory { * Compares flows by whole match */ @Override - public boolean areObjectsEqual(final Match statsFlow, final Match storedFlow) { + public boolean areObjectsEqual(short version, final Match statsFlow, final Match storedFlow) { if (statsFlow == null) { if (storedFlow != null) { return false; } - } else if (!compareMatches(statsFlow, storedFlow)) { + } else if (!compareMatches(version, statsFlow, storedFlow)) { return false; } return true; @@ -337,13 +365,13 @@ public final class MatchComparatorFactory { * @param storedMatch * @return */ - private static boolean compareMatches(final Match statsMatch, final Match storedMatch) { + private static boolean compareMatches(final short version, final Match statsMatch, final Match storedMatch) { if (statsMatch == storedMatch) { return true; } for (SimpleComparator matchComp : MATCH_COMPARATORS) { - if (!matchComp.areObjectsEqual(statsMatch, storedMatch)) { + if (!matchComp.areObjectsEqual(version, statsMatch, storedMatch)) { return false; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java index 456a731687..c6b3174042 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2015, 2017 Cisco 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, @@ -59,6 +59,7 @@ public class MatchComparatorHelper { private static final int IPV4_ADDRESS_LENGTH = 32; private static final int IPV6_ADDRESS_LENGTH = 128; private static final int BYTE_SIZE = 8; + private static final String NO_ETH_MASK = "ff:ff:ff:ff:ff:ff"; /* * Custom EthernetMatch is required because mac address string provided by user in EthernetMatch can be in any case @@ -102,7 +103,7 @@ public class MatchComparatorHelper { } else { verdict = macAddressEquals(statsEthernetMatchFields.getAddress(), storedEthernetMatchFields.getAddress()); if (verdict) { - verdict = macAddressEquals(statsEthernetMatchFields.getMask(), storedEthernetMatchFields.getMask()); + verdict = macAddressMaskEquals(statsEthernetMatchFields.getMask(), storedEthernetMatchFields.getMask()); } } return verdict; @@ -119,6 +120,22 @@ public class MatchComparatorHelper { return verdict; } + static boolean macAddressMaskEquals(final MacAddress statsMacAddressMask, final MacAddress storedMacAddressMask) { + boolean verdict = true; + //User sent the mask with all bit set, which actually means no mask. Switch might just ignore it. + if(statsMacAddressMask == null && storedMacAddressMask != null && + storedMacAddressMask.getValue().equalsIgnoreCase(NO_ETH_MASK)) { + return verdict; + } + final Boolean checkNullValues = checkNullValues(statsMacAddressMask, storedMacAddressMask); + if (checkNullValues != null) { + verdict = checkNullValues; + } else { + verdict = statsMacAddressMask.getValue().equalsIgnoreCase(storedMacAddressMask.getValue()); + } + return verdict; + } + @VisibleForTesting static boolean layer3MatchEquals(final Layer3Match statsLayer3Match, final Layer3Match storedLayer3Match) { boolean verdict = true; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java index 55583e9c54..dfcea9b277 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java @@ -10,6 +10,6 @@ package org.opendaylight.openflowplugin.impl.util; public interface SimpleComparator { - boolean areObjectsEqual(T obj1, T obj2); + boolean areObjectsEqual(short version, T obj1, T obj2); -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/main/resources/org/opendaylight/blueprint/openflowplugin-impl.xml b/openflowplugin-impl/src/main/resources/org/opendaylight/blueprint/openflowplugin-impl.xml index 20b907b416..976efaabee 100644 --- a/openflowplugin-impl/src/main/resources/org/opendaylight/blueprint/openflowplugin-impl.xml +++ b/openflowplugin-impl/src/main/resources/org/opendaylight/blueprint/openflowplugin-impl.xml @@ -6,4 +6,6 @@ - \ No newline at end of file + + + diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java index dc619d61fc..c6fbf45dcc 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java @@ -90,6 +90,7 @@ public class OpenFlowPluginProviderImplTest { provider.setNotificationProviderService(notificationService); provider.setSwitchConnectionProviders(Lists.newArrayList(switchConnectionProvider)); provider.setClusteringSingletonServicesProvider(clusterSingletonServiceProvider); + provider.setEntityOwnershipServiceProvider(entityOwnershipService); } @After diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/MultipartRequestInputFactoryTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/MultipartRequestInputFactoryTest.java index 8eb0f9ff7d..6f0bcb0ff9 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/MultipartRequestInputFactoryTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/MultipartRequestInputFactoryTest.java @@ -15,20 +15,12 @@ import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroup; @@ -58,7 +50,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestDescCase.class); } @Test @@ -111,7 +102,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestAggregateCase.class); } @Test @@ -120,7 +110,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestTableCase.class); } @Test @@ -169,7 +158,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestGroupDescCase.class); } @Test @@ -178,7 +166,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestGroupFeaturesCase.class); } @Test @@ -204,7 +191,6 @@ public class MultipartRequestInputFactoryTest { Assert.assertTrue(mpRqBody instanceof MultipartRequestMeterConfigCase); MultipartRequestMeterConfig mpRq = ((MultipartRequestMeterConfigCase) mpRqBody).getMultipartRequestMeterConfig(); - Assert.assertEquals(OFConstants.OFPM_ALL, mpRq.getMeterId().getValue()); } @Test @@ -213,7 +199,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestMeterFeaturesCase.class); } @Test @@ -235,7 +220,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestPortDescCase.class); } @Test @@ -244,7 +228,6 @@ public class MultipartRequestInputFactoryTest { final MultipartRequestInput mpRqInput = MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType); checkHeader(mpRqInput, mpType, ofVersion); - checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestExperimenterCase.class); } private void checkHeader(MultipartRequestInput mpRqInput, MultipartType mpType, short ofVersion) { @@ -254,9 +237,4 @@ public class MultipartRequestInputFactoryTest { Assert.assertEquals(xid, mpRqInput.getXid().longValue()); } - private void checkEmptyBody(MultipartRequestBody mpRqBody, Class expectedMpRqBodyClass) throws Exception { - Assert.assertTrue(expectedMpRqBodyClass.isAssignableFrom(mpRqBody.getImplementedInterface())); - final String expectedDump = expectedMpRqBodyClass.getSimpleName() + " [augmentation=[]]"; - Assert.assertEquals(expectedDump, String.valueOf(mpRqBody)); - } } \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java index 2af535ac93..e5a3167bc5 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java @@ -476,7 +476,7 @@ public class DeviceContextImplTest { .thenReturn(flowRemovedMdsalBld.build()); // insert flow+flowId into local registry - final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedMdsalBld.build()); + final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowRemovedMdsalBld.build()); final FlowDescriptor flowDescriptor = FlowDescriptorFactory.create((short) 0, new FlowId("ut-ofp:f456")); deviceContext.getDeviceFlowRegistry().store(flowRegKey, flowDescriptor); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java index 33e54b4d7c..17abab3ea3 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java @@ -37,6 +37,8 @@ import org.mockito.stubbing.Answer; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; @@ -107,6 +109,10 @@ public class DeviceManagerImplTest { @Mock private ClusterSingletonServiceProvider clusterSingletonServiceProvider; @Mock + private EntityOwnershipService entityOwnershipService; + @Mock + private EntityOwnershipListenerRegistration entityOwnershipListenerRegistration; + @Mock private ConvertorExecutor convertorExecutor; @Mock private KeyedInstanceIdentifier key; @@ -143,6 +149,7 @@ public class DeviceManagerImplTest { when(mockedDataBroker.newWriteOnlyTransaction()).thenReturn(mockedWriteTransaction); when(mockedWriteTransaction.submit()).thenReturn(mockedFuture); + when(entityOwnershipService.registerListener(any(), any())).thenReturn(entityOwnershipListenerRegistration); final DeviceManagerImpl deviceManager = new DeviceManagerImpl( mockedDataBroker, @@ -153,10 +160,8 @@ public class DeviceManagerImplTest { messageIntelligenceAgency, true, clusterSingletonServiceProvider, - null, - new HashedWheelTimer(), - convertorExecutor, - false); + entityOwnershipService, new HashedWheelTimer(), convertorExecutor, false, null + ); deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler); deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java index 7d02cdb2e1..4cf06d4eb4 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java @@ -15,6 +15,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration; +import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; @@ -48,6 +50,8 @@ public class LifecycleServiceImplTest { private ClusterSingletonServiceProvider clusterSingletonServiceProvider; @Mock private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration; + @Mock + EntityOwnershipListenerRegistration entityOwnershipListenerRegistration; private LifecycleService lifecycleService; @@ -63,9 +67,9 @@ public class LifecycleServiceImplTest { Mockito.when(clusterSingletonServiceProvider.registerClusterSingletonService(Mockito.any())) .thenReturn(clusterSingletonServiceRegistration); - Mockito.when(deviceContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null)); - Mockito.when(statContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null)); - Mockito.when(rpcContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null)); + Mockito.when(deviceContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null)); + Mockito.when(statContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null)); + Mockito.when(rpcContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null)); lifecycleService = new LifecycleServiceImpl(); lifecycleService.setDeviceContext(deviceContext); @@ -86,9 +90,9 @@ public class LifecycleServiceImplTest { @Test public void closeServiceInstance() throws Exception { lifecycleService.closeServiceInstance().get(); - Mockito.verify(statContext).stopClusterServices(false); - Mockito.verify(deviceContext).stopClusterServices(false); - Mockito.verify(rpcContext).stopClusterServices(false); + Mockito.verify(statContext).stopClusterServices(); + Mockito.verify(deviceContext).stopClusterServices(); + Mockito.verify(rpcContext).stopClusterServices(); } @Test diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImplTest.java index dafa7ca27e..250d13615c 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImplTest.java @@ -33,6 +33,7 @@ import org.mockito.runners.MockitoJUnitRunner; 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.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor; import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; @@ -73,9 +74,9 @@ public class DeviceFlowRegistryImplTest { public void setUp() throws Exception { nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(new NodeId(NODE_ID))); when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction); - deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, nodeInstanceIdentifier); + deviceFlowRegistry = new DeviceFlowRegistryImpl(OFConstants.OFP_VERSION_1_3, dataBroker, nodeInstanceIdentifier); final FlowAndStatisticsMapList flowStats = TestFlowHelper.createFlowAndStatisticsMapListBuilder(1).build(); - key = FlowRegistryKeyFactory.create(flowStats); + key = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flowStats); descriptor = FlowDescriptorFactory.create(key.getTableId(), new FlowId("ut:1")); Assert.assertEquals(0, deviceFlowRegistry.getAllFlowDescriptors().size()); @@ -103,7 +104,7 @@ public class DeviceFlowRegistryImplTest { .build(); final Map allFlowDescriptors = testFill(path, flowCapableNode); - final FlowRegistryKey key = FlowRegistryKeyFactory.create(flow); + final FlowRegistryKey key = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flow); InOrder order = inOrder(dataBroker, readOnlyTransaction); order.verify(dataBroker).newReadOnlyTransaction(); @@ -178,7 +179,7 @@ public class DeviceFlowRegistryImplTest { // store new key with old value final FlowAndStatisticsMapList flowStats = TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build(); - final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(flowStats); + final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flowStats); deviceFlowRegistry.store(key2, descriptor); Assert.assertEquals(2, deviceFlowRegistry.getAllFlowDescriptors().size()); Assert.assertEquals("ut:1", deviceFlowRegistry.retrieveIdForFlow(key2).getFlowId().getValue()); @@ -197,7 +198,7 @@ public class DeviceFlowRegistryImplTest { //store new key final String alienPrefix = "#UF$TABLE*2-"; - final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build()); + final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build()); newFlowId = deviceFlowRegistry.storeIfNecessary(key2); Assert.assertTrue(newFlowId.getValue().startsWith(alienPrefix)); @@ -238,4 +239,4 @@ public class DeviceFlowRegistryImplTest { return null; } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java index 26313fc95f..35e08e6cdf 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java @@ -71,8 +71,8 @@ public class FlowRegistryKeyFactoryTest { HashSet flowRegistryKeys = new HashSet<>(); for (FlowAndStatisticsMapList item : flowStats.getFlowAndStatisticsMapList()) { - final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(item); - final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(item); + final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item); + final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item); flowRegistryKeys.add(key1); flowRegistryKeys.add(key1); flowRegistryKeys.add(key2); @@ -83,7 +83,7 @@ public class FlowRegistryKeyFactoryTest { @Test public void testEqualsNegative() throws Exception { final FlowAndStatisticsMapList flowStatisticsMapList1 = TestFlowHelper.createFlowAndStatisticsMapListBuilder(1).build(); - final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(flowStatisticsMapList1); + final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapList1); FlowRegistryKey key2; FlowAndStatisticsMapListBuilder flowStatisticsMapListBld2; @@ -91,19 +91,19 @@ public class FlowRegistryKeyFactoryTest { // different priority flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1); flowStatisticsMapListBld2.setPriority(flowStatisticsMapListBld2.getPriority() + 1); - key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build()); + key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build()); Assert.assertFalse(key1.equals(key2)); // different match flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1); flowStatisticsMapListBld2.setMatch(new MatchBuilder().build()); - key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build()); + key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build()); Assert.assertFalse(key1.equals(key2)); // different tableId flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1); flowStatisticsMapListBld2.setTableId((short) (flowStatisticsMapListBld2.getTableId() + 1)); - key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build()); + key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build()); Assert.assertFalse(key1.equals(key2)); Assert.assertFalse(key1.equals(null)); @@ -119,7 +119,7 @@ public class FlowRegistryKeyFactoryTest { .setPriority(2) .setTableId((short) 0); - FlowRegistryKey flow1Hash = FlowRegistryKeyFactory.create(flow1Builder.build()); + FlowRegistryKey flow1Hash = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flow1Builder.build()); LOG.info("flowHash1: {}", flow1Hash.hashCode()); @@ -129,7 +129,7 @@ public class FlowRegistryKeyFactoryTest { .setCookie(new FlowCookie(BigInteger.valueOf(148))) .setMatch(match2Builder.build()); - FlowRegistryKey flow2Hash = FlowRegistryKeyFactory.create(flow2Builder.build()); + FlowRegistryKey flow2Hash = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flow2Builder.build()); LOG.info("flowHash2: {}", flow2Hash.hashCode()); Assert.assertNotSame(flow1Hash, flow2Hash); @@ -148,7 +148,7 @@ public class FlowRegistryKeyFactoryTest { FlowBuilder fb1 = new FlowBuilder(flow1Builder.build()); fb1.setTableId(null); try { - FlowRegistryKeyFactory.create(fb1.build()); + FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb1.build()); Assert.fail("hash creation should have failed because of NPE"); } catch (Exception e) { // expected @@ -158,7 +158,7 @@ public class FlowRegistryKeyFactoryTest { FlowBuilder fb2 = new FlowBuilder(flow1Builder.build()); fb2.setPriority(null); try { - FlowRegistryKeyFactory.create(fb2.build()); + FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb2.build()); } catch (Exception e) { // not expected Assert.fail("no exception was expected while hash was creating."); @@ -166,7 +166,7 @@ public class FlowRegistryKeyFactoryTest { FlowBuilder fb3 = new FlowBuilder(flow1Builder.build()); fb3.setCookie(null); - FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(fb3.build()); + FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb3.build()); Assert.assertNotNull(flowRegistryKey.getCookie()); Assert.assertEquals(OFConstants.DEFAULT_COOKIE, flowRegistryKey.getCookie()); } @@ -176,7 +176,7 @@ public class FlowRegistryKeyFactoryTest { FlowsStatisticsUpdate flowStats = FLOWS_STATISTICS_UPDATE_BUILDER.build(); for (FlowAndStatisticsMapList item : flowStats.getFlowAndStatisticsMapList()) { - FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(item); + FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item); FlowRegistryKey lastHash = null; if (null != lastHash) { assertNotEquals(lastHash, flowRegistryKey); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java index 098ef4dd86..5d15eff5cd 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -116,7 +117,7 @@ public class MultipartRequestOnTheFlyCallbackTest { private final short tableId = 0; @Before - public void initialization() { + public void initialization() throws Exception{ when(mockedDeviceContext.getMessageSpy()).thenReturn(new MessageIntelligenceAgencyImpl()); when(mockedNodeId.toString()).thenReturn(DUMMY_NODE_ID); when(mockedPrimaryConnection.getNodeId()).thenReturn(mockedNodeId); @@ -143,8 +144,11 @@ public class MultipartRequestOnTheFlyCallbackTest { final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder(); flowNodeBuilder.setTable(Collections.
emptyList()); final Optional flowNodeOpt = Optional.of(flowNodeBuilder.build()); + final CheckedFuture, ReadFailedException> flowNodeFuture = Futures.immediateCheckedFuture(flowNodeOpt); - when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture); + final CheckedFuture, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture); + when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFutureSpy); + when(flowNodeFutureSpy.get()).thenReturn(flowNodeOpt); when(mockedDeviceContext.getReadTransaction()).thenReturn(mockedReadOnlyTx); dummyRequestContext = new AbstractRequestContext>(DUMMY_XID) { @@ -234,7 +238,10 @@ public class MultipartRequestOnTheFlyCallbackTest { final Optional flowNodeOpt = Optional.of(flowNodeBuilder.build()); final CheckedFuture, ReadFailedException> flowNodeFuture = Futures .immediateCheckedFuture(flowNodeOpt); - when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture); + final CheckedFuture, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture); + + when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFutureSpy); + when(flowNodeFutureSpy.get()).thenReturn(flowNodeOpt); when(mockedDeviceContext.getReadTransaction()).thenReturn(mockedReadOnlyTx); multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build()); @@ -260,20 +267,55 @@ public class MultipartRequestOnTheFlyCallbackTest { */ @Test public void testOnSuccessWithValidMultipart2() throws Exception { + final MatchBuilder matchBuilder = new MatchBuilder() + .setMatchEntry(Collections.emptyList()); + final FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder() + .setTableId(tableId) + .setPriority(2) + .setCookie(BigInteger.ZERO) + .setByteCount(BigInteger.TEN) + .setPacketCount(BigInteger.ONE) + .setDurationSec(11L) + .setDurationNsec(12L) + .setMatch(matchBuilder.build()) + .setFlags(new FlowModFlags(true, false, false, false, false)); + final MultipartReplyFlowBuilder multipartReplyFlowBuilder = new MultipartReplyFlowBuilder() + .setFlowStats(Collections.singletonList(flowStatsBuilder.build())); + final MultipartReplyFlowCaseBuilder multipartReplyFlowCaseBuilder = new MultipartReplyFlowCaseBuilder() + .setMultipartReplyFlow(multipartReplyFlowBuilder.build()); final MultipartReplyMessageBuilder mpReplyMessage = new MultipartReplyMessageBuilder() - .setType(MultipartType.OFPMPDESC) - .setFlags(new MultipartRequestFlags(false)); + .setType(MultipartType.OFPMPFLOW) + .setFlags(new MultipartRequestFlags(false)) + .setMultipartReplyBody(multipartReplyFlowCaseBuilder.build()) + .setXid(21L); - multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build()); + final InstanceIdentifier nodePath = mockedDeviceInfo.getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class); + final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder(); + final TableBuilder tableDataBld = new TableBuilder(); + tableDataBld.setId(tableId); + flowNodeBuilder.setTable(Collections.singletonList(tableDataBld.build())); + final Optional flowNodeOpt = Optional.of(flowNodeBuilder.build()); + final CheckedFuture, ReadFailedException> flowNodeFuture = Futures + .immediateCheckedFuture(flowNodeOpt); + final CheckedFuture, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture); - final RpcResult> actualResult = dummyRequestContext.getFuture().get(); - assertNotNull(actualResult.getErrors()); - assertTrue(actualResult.getErrors().isEmpty()); - assertNotNull(actualResult.getResult()); - assertTrue(actualResult.getResult().isEmpty()); + when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFutureSpy); + when(flowNodeFutureSpy.get()).thenReturn(flowNodeOpt); + when(mockedDeviceContext.getReadTransaction()).thenReturn(mockedReadOnlyTx); - Mockito.verify(mockedFlowRegistry, Mockito.never()).storeIfNecessary(Matchers.any()); - Mockito.verify(mockedDeviceContext, Mockito.never()).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), - Matchers.any(), Matchers.any()); + multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build()); + final InstanceIdentifier
tableIdent = nodePath.child(Table.class, new TableKey(tableId)); + + verify(mockedReadOnlyTx, times(1)).read(LogicalDatastoreType.OPERATIONAL, nodePath); + verify(mockedReadOnlyTx, times(1)).close(); + verify(mockedDeviceContext, times(1)).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), + eq(tableIdent), Matchers.
any()); + /* + * One call for Table one call for Flow + * we are not able to create Flow InstanceIdentifier because we are missing FlowId + */ + verify(mockedDeviceContext, times(2)).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), + Matchers. any(), Matchers. any()); } } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java index fafa4df3f8..92180d798a 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java @@ -106,7 +106,7 @@ public abstract class ServiceMocking { when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext); when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy); - when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(dataBroker, NODE_II)); + when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(DUMMY_VERSION, dataBroker, NODE_II)); when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState); when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo); when(mockedDeviceContext.getMultiMsgCollector(Matchers.any())).thenReturn(multiMessageCollector); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java index 65abd670d9..461c92c5df 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java @@ -40,6 +40,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue; +import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; @@ -164,7 +165,7 @@ public class StatisticsManagerImplTest { when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo); when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext); when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy); - when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(dataBroker, nodePath)); + when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(OFConstants.OFP_VERSION_1_3, dataBroker, nodePath)); when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState); when(mockedDeviceContext.getMultiMsgCollector( Matchers.>>any())).thenAnswer( diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelperTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelperTest.java new file mode 100644 index 0000000000..5c29fc8930 --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelperTest.java @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2014, 2017 Cisco 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.openflowplugin.impl.util; + +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * @author sai.marapareddy@gmail.com (arbitrary masks) + */ + +/** + * test of {@link MatchComparatorHelper} + */ +public class MatchComparatorHelperTest { + + /** + * mask for /32 + */ + private static final int DEFAULT_IPV4_MASK = 0xffffffff; + + /** + * mask for /30 + */ + private static final int IPV4_30_MASK = 0xfffffffc; + private static final int IP_ADDRESS = 0xC0A80101; + + /** + * The test of conversion valid IP addres without mask to binary form. + */ + @Test + public void validIpWithoutMaskTest() { + IntegerIpAddress intIp = MatchComparatorHelper.strIpToIntIp("192.168.1.1"); + assertEquals(IP_ADDRESS, intIp.getIp()); + assertEquals(DEFAULT_IPV4_MASK, intIp.getMask()); + } + + /** + * The test of conversion of valid IP address with valid mask to binary form. + */ + @Test + public void validIpWithValidMaskTest() { + IntegerIpAddress intIp = MatchComparatorHelper.strIpToIntIp("192.168.1.1/30"); + assertEquals(IP_ADDRESS, intIp.getIp()); + assertEquals(IPV4_30_MASK, intIp.getMask()); + } + + /** + * The test of conversion of valid IP address invalid mask to binary form. + */ + @Test + public void validIpWithInvalidMaskTest() { + try { + MatchComparatorHelper.strIpToIntIp("192.168.1.1/40"); + } catch (IllegalStateException e) { + assertEquals("Valid values for mask are from range 0 - 32. Value 40 is invalid.", e.getMessage()); + return; + } + fail("IllegalStateException was awaited (40 subnet is invalid)"); + } + + /** + * The test of conversion invalid IP address with valid mask to binary form. + */ + @Test + public void invalidIpWithValidMaskTest() { + try { + MatchComparatorHelper.strIpToIntIp("257.168.1.1/25"); + } catch (IllegalArgumentException e) { + assertEquals("'257.168.1.1' is not an IP string literal.", e.getMessage()); + } + } + + @Test + public void ethernetMatchEqualsTest() { + final EthernetMatchBuilder statsEthernetBuilder = new EthernetMatchBuilder(); + final EthernetMatchBuilder storedEthernetBuilder = new EthernetMatchBuilder(); + + assertEquals(true, MatchComparatorHelper.ethernetMatchEquals(null, null)); + + statsEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress( + new MacAddress("11:22:33:44:55:66")).build()); + storedEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress( + new MacAddress("11:22:33:44:55:77")).build()); + assertEquals(false, + MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build())); + + storedEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress( + new MacAddress("11:22:33:44:55:66")).build()); + statsEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress( + new MacAddress("66:55:44:33:22:11")).build()); + storedEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress( + new MacAddress("77:55:44:33:22:11")).build()); + assertEquals(false, + MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build())); + + storedEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress( + new MacAddress("66:55:44:33:22:11")).build()); + statsEthernetBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) 1)).build()); + storedEthernetBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) 1)).build()); + assertEquals(true, + MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build())); + + statsEthernetBuilder.setEthernetType(null).build(); + assertEquals(false, + MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build())); + + storedEthernetBuilder.setEthernetType(null).build(); + assertEquals(true, + MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build())); + + } + + // Please see following bug for more details https://bugs.opendaylight.org/show_bug.cgi?id=7910 + @Test + public void ethernetMatchWithFullMaskTest() { + final EthernetSourceBuilder statsBuilder = new EthernetSourceBuilder(); + final EthernetSourceBuilder storedBuilder = new EthernetSourceBuilder(); + + assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(null, null)); + + statsBuilder.setAddress(new MacAddress("11:22:33:44:55:66")); + + storedBuilder.setAddress(new MacAddress("11:22:33:44:55:66")); + storedBuilder.setMask(new MacAddress("FF:FF:FF:FF:FF:FF")); + + assertEquals(true, + MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build())); + } + + @Test + public void ethernetMatchFieldsEqualsTest() { + final EthernetSourceBuilder statsBuilder = new EthernetSourceBuilder(); + final EthernetSourceBuilder storedBuilder = new EthernetSourceBuilder(); + + assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(null, null)); + + statsBuilder.setAddress(new MacAddress("11:22:33:44:55:66")); + storedBuilder.setAddress(new MacAddress("11:22:33:44:55:77")); + assertEquals(false, + MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build())); + + storedBuilder.setAddress(new MacAddress("11:22:33:44:55:66")); + assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build())); + } + + @Test + public void macAddressEqualsTest() { + assertEquals(true, MatchComparatorHelper.macAddressEquals(null, null)); + assertEquals(true, MatchComparatorHelper.macAddressEquals(new MacAddress("11:22:33:44:55:66"), new MacAddress( + "11:22:33:44:55:66"))); + assertEquals(false, MatchComparatorHelper.macAddressEquals(new MacAddress("11:22:33:44:55:66"), new MacAddress( + "11:22:33:44:55:77"))); + } + + @Test + public void checkNullValuesTest() { + assertEquals(false, MatchComparatorHelper.checkNullValues(null, "")); + assertEquals(false, MatchComparatorHelper.checkNullValues("", null)); + assertEquals(true, MatchComparatorHelper.checkNullValues(null, null)); + assertTrue(MatchComparatorHelper.checkNullValues("", "") == null); + } + + @Test + public void compareIpv4PrefixNullSafeTest() { + assertEquals(true, MatchComparatorHelper.compareIpv4PrefixNullSafe(null, null)); + assertEquals(true, MatchComparatorHelper.compareIpv4PrefixNullSafe(new Ipv4Prefix("192.168.1.1/31"), + new Ipv4Prefix("192.168.1.1/31"))); + + assertEquals(false, MatchComparatorHelper.compareIpv4PrefixNullSafe(new Ipv4Prefix("192.168.1.1/31"), + new Ipv4Prefix("191.168.1.1/31"))); + } + + @Test + public void compareStringNullSafeTest() { + assertEquals(true, MatchComparatorHelper.compareStringNullSafe(null,null)); + assertEquals(true, MatchComparatorHelper.compareStringNullSafe("Hello", "Hello")); + assertEquals(false, MatchComparatorHelper.compareStringNullSafe("Hello", "hello")); + } + + private static final int ip_192_168_1_1 = 0xC0A80101; + private static final int ip_192_168_1_4 = 0xC0A80104; + + @Test + public void ipBasedMatchTest() { + // are equals because only IP address is compared + assertEquals(true, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 32), + new IntegerIpAddress(ip_192_168_1_1, 16))); + } + + @Test + public void ipAndMaskBasedMatchTest() { + // true because both cases are network 192.168.1.0 + assertEquals(true, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 31), + new IntegerIpAddress(ip_192_168_1_1, 30))); + + // false because first is network 192.168.1.0 and second is 192.168.1.4 + assertEquals(false, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 31), + new IntegerIpAddress(ip_192_168_1_4, 30))); + } + + @Test + public void layer3MatchEqualsTest() { + final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder(); + final Ipv4MatchBuilder storedBuilder = new Ipv4MatchBuilder(); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/30")); + storedBuilder.setIpv4Destination(new Ipv4Prefix("191.168.1.1/30")); + assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null)); + assertEquals(true, + MatchComparatorHelper.layer3MatchEquals(new ArpMatchBuilder().build(), new ArpMatchBuilder().build())); + } + + @Test + public void layer3MatchEqualsIpv6Test() { + final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder(); + final Ipv6MatchBuilder storedBuilder = new Ipv6MatchBuilder(); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + + statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:5D99/64")); + storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64")); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + + statsBuilder.setIpv6Destination(new Ipv6Prefix("aabb:1234:2acf:000d:0000:0000:0000:5d99/64")); + storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64")); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + + statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000C:0000:0000:0000:5D99/64")); + storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64")); + assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + + statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000C:0000:0000:0000:5D99/63")); + storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/63")); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + + statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:5D99/63")); + storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000E:0000:0000:0000:4D99/63")); + assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + } + + @Test + public void layer3MatchEqualsIpv4ArbitraryMaskTest(){ + final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder(); + final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder(); + assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build())); + statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/24")); + storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1")); + storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.255.0")); + statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/24")); + storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1")); + storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.255.255.0")); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null)); + + } + + @Test + public void layer3MatchEqualsIpv4ArbitraryMaskRandomTest() { + final Ipv4MatchArbitraryBitMaskBuilder statsBuilder = new Ipv4MatchArbitraryBitMaskBuilder(); + final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder(); + assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build())); + statsBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1")); + statsBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255")); + storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1")); + storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255")); + statsBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.0.0.1")); + statsBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255")); + storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.7.1.1")); + storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255")); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null)); + } + + @Test + public void layer3MatchEqualsIpv4ArbitraryMaskEqualsNullTest() { + final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder(); + final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder(); + assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build())); + statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.0.1/32")); + storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1")); + statsBuilder.setIpv4Destination(new Ipv4Prefix("192.1.0.0/32")); + storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.1.0.0")); + assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null)); + } + + @Test + public void layer3MatchEqualsIpv4ArbitraryEmptyBitMaskTest(){ + final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder(); + final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder(); + assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build())); + statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/32")); + storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1")); + statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/32")); + storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1")); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build())); + assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null)); + } + + @Test + public void extractIpv4AddressTest() { + Ipv4Address ipAddress = new Ipv4Address("1.1.1.1"); + DottedQuad netMask = new DottedQuad("255.255.255.0"); + String extractedIpAddress; + extractedIpAddress = MatchComparatorHelper.normalizeIpv4Address(ipAddress,netMask); + assertEquals(extractedIpAddress,"1.1.1.0"); + } + + @Test + public void convertArbitraryMaskToByteArrayTest() { + int value = 0xffffffff; + byte[] bytes = new byte[]{ + (byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) }; + byte[] maskBytes; + maskBytes = MatchComparatorHelper.convertArbitraryMaskToByteArray(new DottedQuad("255.255.255.255")); + for (int i=0; i salPacketIn = packetInV10Translator.translate(cookie, sessionContextOFImpl, message); - //TODO: rewrite to object and involve object comparison in Assert - String expectedString = "[PacketReceived [_ingress=NodeConnectorRef [_value=KeyedInstanceIdentifier" - + "{targetType=interface org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector," - + " path=[org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes," - + " org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node[" - + "key=NodeKey [_id=Uri [_value=openflow:" - + datapathId.toString() - + "]]]," - + " org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector[" - + "key=NodeConnectorKey [_id=Uri [_value=openflow:" - + datapathId.toString() - + ":" - + message.getInPort().toString() - + "]]]]}], _packetInReason=class org.opendaylight.yang.gen.v1.urn.opendaylight." - + "packet.service.rev130709.SendToController, _payload=[115, 101, 110, 100, 79, 117," - + " 116, 112, 117, 116, 77, 115, 103, 95, 84, 69, 83, 84], augmentation=[]]]"; - Assert.assertEquals(expectedString, salPacketIn.toString()); + Assert.assertEquals(Collections.singletonList(new PacketReceivedBuilder() + .setIngress(InventoryDataServiceUtil.nodeConnectorRefFromDatapathIdPortno(datapathId, (long) message.getInPort(), OpenflowVersion.OF10)) + .setPacketInReason(SendToController.class) + .setPayload(data) + .build()).toString(), salPacketIn.toString()); + LOG.debug("Test translate done."); }