Merge "Bug 6110: Fixed bugs in statistics manager due to race condition." into stable...
authorAnil Vishnoi <vishnoianil@gmail.com>
Sat, 11 Mar 2017 03:26:43 +0000 (03:26 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 11 Mar 2017 03:26:43 +0000 (03:26 +0000)
75 files changed:
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java
applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml
applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java
applications/lldp-speaker/src/main/resources/org/opendaylight/blueprint/lldp-speaker.xml
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommit.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitFlow.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitGroup.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitMeter.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitQueue.java
applications/statistics-manager/src/test/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommitTest.java
extension/openflowplugin-extension-api/src/main/java/org/opendaylight/openflowplugin/extension/api/path/ActionPath.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/LearnConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PopNshConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/PushNshConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertor.java
extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertorTest.java
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/FinTimeoutConvertorTest.java
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/MultipathConvertorTest.java
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/OutputRegConvertorTest.java
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorTest.java
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegMoveConvertorTest.java
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ResubmitConvertorTest.java
model/model-flow-base/src/main/yang/opendaylight-flow-types.yang
model/model-flow-service/src/main/yang/sal-flow.yang
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderFactoryImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactory.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslator.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorFactory.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java
openflowplugin-impl/src/main/resources/org/opendaylight/blueprint/openflowplugin-impl.xml
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/MultipartRequestInputFactoryTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelperTest.java [new file with mode: 0644]
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/translator/FlowRemovedTranslator.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/translator/PacketInV10TranslatorTest.java

index 54360a005dee373773f0d9fc2ff5f98da867413a..e6876ae401c461cc48502886f73bae9d052e4149 100644 (file)
@@ -25,25 +25,26 @@ public class DeviceMastership implements ClusterSingletonService, AutoCloseable
     private static final Logger LOG = LoggerFactory.getLogger(DeviceMastership.class);
     private final NodeId nodeId;
     private final ServiceGroupIdentifier identifier;
-    private final ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
+    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
     private boolean deviceMastered;
 
     public DeviceMastership(final NodeId nodeId, final ClusterSingletonServiceProvider clusterSingletonService) {
         this.nodeId = nodeId;
         this.identifier = ServiceGroupIdentifier.create(nodeId.getValue());
         this.deviceMastered = false;
-        clusterSingletonServiceRegistration = clusterSingletonService.registerClusterSingletonService(this);
+        this.clusterSingletonServiceProvider = clusterSingletonService;
     }
 
     @Override
     public void instantiateServiceInstance() {
-        LOG.debug("FRM started for: {}", nodeId.getValue());
+        LOG.info("FRM started for: {}", nodeId.getValue());
         deviceMastered = true;
     }
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
-        LOG.debug("FRM stopped for: {}", nodeId.getValue());
+        LOG.info("FRM stopped for: {}", nodeId.getValue());
         deviceMastered = false;
         return Futures.immediateFuture(null);
     }
@@ -68,4 +69,8 @@ public class DeviceMastership implements ClusterSingletonService, AutoCloseable
         return deviceMastered;
     }
 
+    public void registerClusterSingletonService() {
+        LOG.info("Registering FRM as a cluster singleton service listner for service id : {}",getIdentifier());
+        clusterSingletonServiceRegistration = clusterSingletonServiceProvider.registerClusterSingletonService(this);
+    }
 }
index dd7c2721c7093830836384ac065dfaa54a05c881..2286338b07934acbd655416532676b33995e72f9 100644 (file)
@@ -10,35 +10,41 @@ package org.opendaylight.openflowplugin.applications.frm.impl;
 
 import com.google.common.annotations.VisibleForTesting;
 import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Manager for clustering service registrations of {@link DeviceMastership}.
  */
-public class DeviceMastershipManager {
+public class DeviceMastershipManager implements OpendaylightInventoryListener, AutoCloseable{
     private static final Logger LOG = LoggerFactory.getLogger(DeviceMastershipManager.class);
     private final ClusterSingletonServiceProvider clusterSingletonService;
+    private final ListenerRegistration<?> notifListenerRegistration;
     private final ConcurrentHashMap<NodeId, DeviceMastership> deviceMasterships = new ConcurrentHashMap();
 
-    public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService) {
+    public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService,
+                                   final NotificationProviderService notificationService) {
         this.clusterSingletonService = clusterSingletonService;
+        this.notifListenerRegistration = notificationService.registerNotificationListener(this);
     }
 
     public void onDeviceConnected(final NodeId nodeId) {
-        LOG.debug("FRM service registered for: {}", nodeId.getValue());
-        final DeviceMastership mastership = new DeviceMastership(nodeId, clusterSingletonService);
-        deviceMasterships.put(nodeId, mastership);
+        //No-op
     }
 
     public void onDeviceDisconnected(final NodeId nodeId) {
-        final DeviceMastership mastership = deviceMasterships.remove(nodeId);
-        if (mastership != null) {
-            mastership.close();
-        }
-        LOG.debug("FRM service unregistered for: {}", nodeId.getValue());
+        //No-op
     }
 
     public boolean isDeviceMastered(final NodeId nodeId) {
@@ -49,4 +55,40 @@ public class DeviceMastershipManager {
     ConcurrentHashMap<NodeId, DeviceMastership> getDeviceMasterships() {
         return deviceMasterships;
     }
+
+    @Override
+    public void onNodeUpdated(NodeUpdated notification) {
+        LOG.debug("NodeUpdate notification received : {}", notification);
+        DeviceMastership membership = deviceMasterships.computeIfAbsent(notification.getId(), device ->
+                new DeviceMastership(notification.getId(), clusterSingletonService));
+        membership.registerClusterSingletonService();
+    }
+
+    @Override
+    public void onNodeConnectorUpdated(NodeConnectorUpdated notification) {
+        //Not published by plugin
+    }
+
+    @Override
+    public void onNodeRemoved(NodeRemoved notification) {
+        LOG.debug("NodeRemoved notification received : {}", notification);
+        NodeId nodeId = notification.getNodeRef().getValue().firstKeyOf(Node.class).getId();
+        final DeviceMastership mastership = deviceMasterships.remove(nodeId);
+        if (mastership != null) {
+            mastership.close();
+            LOG.info("Unregistered FRM cluster singleton service for service id : {}", nodeId.getValue());
+        }
+    }
+
+    @Override
+    public void onNodeConnectorRemoved(NodeConnectorRemoved notification) {
+        //Not published by plugin
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (notifListenerRegistration != null) {
+            notifListenerRegistration.close();
+        }
+    }
 }
index 61665cb59b587510631603ab100d5b7baba88e73..093ed96782e1ddd77cb59b18e48635f754be0fc4 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
@@ -74,16 +75,20 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
     private final ForwardingRulesManagerConfig forwardingRulesManagerConfig;
     private FlowNodeConnectorInventoryTranslatorImpl flowNodeConnectorInventoryTranslatorImpl;
     private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private final NotificationProviderService notificationService;
     private DeviceMastershipManager deviceMastershipManager;
 
     public ForwardingRulesManagerImpl(final DataBroker dataBroker,
                                       final RpcConsumerRegistry rpcRegistry,
                                       final ForwardingRulesManagerConfig config,
-                                      final ClusterSingletonServiceProvider clusterSingletonService) {
+                                      final ClusterSingletonServiceProvider clusterSingletonService,
+                                      final NotificationProviderService notificationService) {
         this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
         this.forwardingRulesManagerConfig = Preconditions.checkNotNull(config, "Configuration for FRM cannot be null");
         this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonService,
                 "ClusterSingletonService provider can not be null");
+        this.notificationService = Preconditions.checkNotNull(notificationService, "Notification publisher service is" +
+                " not available");
 
         Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
 
@@ -99,7 +104,8 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
 
     @Override
     public void start() {
-        this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider);
+        this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider,
+                notificationService);
         this.flowListener = new FlowForwarder(this, dataService);
         this.groupListener = new GroupForwarder(this, dataService);
         this.meterListener = new MeterForwarder(this, dataService);
@@ -132,6 +138,9 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
             this.nodeListener.close();
             this.nodeListener = null;
         }
+        if (deviceMastershipManager != null) {
+            deviceMastershipManager.close();
+        }
     }
 
     @Override
index b6f154e06524e1cca1ad31685f648da321d310da..c7d81bdc0213e165b918b736508f7a142e1c9387 100644 (file)
@@ -5,6 +5,7 @@
 
   <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
   <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+  <reference id="notificationService" interface="org.opendaylight.controller.sal.binding.api.NotificationProviderService"/>
   <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
   <odl:clustered-app-config id="frmConfig"
@@ -16,5 +17,6 @@
     <argument ref="rpcRegistry"/>
     <argument ref="frmConfig"/>
     <argument ref="clusterSingletonService"/>
+    <argument ref="notificationService"/>
   </bean>
 </blueprint>
\ No newline at end of file
index 870eb6be1bb8542eb6ae6965148a15e24769542f..31a83f605c175b375b5eeafc6a58632a6bec9822 100644 (file)
@@ -16,10 +16,18 @@ import org.mockito.Matchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
  * Test for {@link DeviceMastershipManager}.
@@ -32,10 +40,13 @@ public class DeviceMastershipManagerTest {
     private ClusterSingletonServiceRegistration registration;
     @Mock
     private ClusterSingletonServiceProvider clusterSingletonService;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() throws Exception {
-        deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService);
+        deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService,
+                notificationService);
         Mockito.when(clusterSingletonService.registerClusterSingletonService(Matchers.<ClusterSingletonService>any()))
                 .thenReturn(registration);
     }
@@ -44,22 +55,29 @@ public class DeviceMastershipManagerTest {
     public void testOnDeviceConnectedAndDisconnected() throws Exception {
         // no context
         Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
-        // create context - register
-        deviceMastershipManager.onDeviceConnected(NODE_ID);
+        NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+        nodeUpdatedBuilder.setId(NODE_ID);
+        deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
         DeviceMastership serviceInstance = deviceMastershipManager.getDeviceMasterships().get(NODE_ID);
         Assert.assertNotNull(serviceInstance);
-        Mockito.verify(clusterSingletonService).registerClusterSingletonService(serviceInstance);
         // destroy context - unregister
         deviceMastershipManager.onDeviceDisconnected(NODE_ID);
+        Assert.assertNotNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
+        NodeRemovedBuilder nodeRemovedBuilder = new NodeRemovedBuilder();
+        InstanceIdentifier<Node> nodeIId = InstanceIdentifier.create(Nodes.class).
+                child(Node.class, new NodeKey(NODE_ID));
+        nodeRemovedBuilder.setNodeRef(new NodeRef(nodeIId));
+        deviceMastershipManager.onNodeRemoved(nodeRemovedBuilder.build());
         Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
-        Mockito.verify(registration).close();
     }
 
     @Test
     public void testIsDeviceMasteredOrSlaved() {
         // no context
         Assert.assertFalse(deviceMastershipManager.isDeviceMastered(NODE_ID));
-        deviceMastershipManager.onDeviceConnected(NODE_ID);
+        NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+        nodeUpdatedBuilder.setId(NODE_ID);
+        deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
         // is master
         deviceMastershipManager.getDeviceMasterships().get(NODE_ID).instantiateServiceInstance();
         Assert.assertTrue(deviceMastershipManager.isDeviceMastered(NODE_ID));
index acada3752301bb3fb142bcb17a5b23d808f746f4..997c556f756b412a5e40e2427ba0e8e70eb4d5e8 100644 (file)
@@ -20,6 +20,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -63,6 +64,8 @@ public class FlowListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -70,7 +73,8 @@ public class FlowListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index e33a88d52aca9eb6ec7ea83342a8d3e3ea84f493..91f437c955a4bde97c7f71fae0064a37b601aca5 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -53,6 +54,8 @@ public class GroupListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -60,7 +63,8 @@ public class GroupListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index bab64fc88575015472ad3c50cd87936797447373..1afff7b91405f82da35a5d9596b07948becd4274 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -53,6 +54,8 @@ public class MeterListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -60,7 +63,8 @@ public class MeterListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index c0ee47212444c710ad5c9c0b2c717e5df19bca6d..4834f9f84037d24bb8892fbfd1f5e93cf4c10317 100644 (file)
@@ -16,6 +16,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
@@ -35,6 +36,8 @@ public class NodeListenerTest extends FRMTest {
     RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
     @Mock
     ClusterSingletonServiceProvider clusterSingletonService;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -42,7 +45,8 @@ public class NodeListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
     }
 
index 1dd9697173988dcd40e8888a004701514f5e33b8..1060e795bde9eb1268effc99027183eb3840d5b9 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -48,6 +49,8 @@ public class TableFeaturesListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -55,7 +58,8 @@ public class TableFeaturesListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index ca8fa54dd97aae6a98ecf0fbb8c6045b31f63c14..d07cc2d1eeee4de99a88a18100f8370384f6f8be 100644 (file)
@@ -14,7 +14,7 @@
     ]]></odl:default-config>
   </odl:clustered-app-config>
 
-  <odl:rpc-service id="packetProcessingService"
+  <odl:action-service id="packetProcessingService"
       interface="org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService"/>
 
   <bean id="lldpSpeaker" class="org.opendaylight.openflowplugin.applications.lldpspeaker.LLDPSpeaker"
@@ -40,4 +40,4 @@
   </bean>
 
   <odl:rpc-implementation ref="operationalStatusChangeService"/>
-</blueprint>
\ No newline at end of file
+</blueprint>
index e6dfc888f9a971d17484215d30b4e79409d6e613..740f82378ced82b5b905e24d8a0d3d4b1fc0c196 100644 (file)
@@ -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<T extends DataObject, N extends N
 
     protected final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier<T>, Integer>> mapNodesForDelete = new ConcurrentHashMap<>();
     protected final Map<InstanceIdentifier<Node>, Integer> mapNodeFeautureRepeater = new ConcurrentHashMap<>();
+    protected final Map<InstanceIdentifier<Node>, ArrayList<T>> removedDataBetweenStatsCycle = new
+            ConcurrentHashMap<>();
 
     private final Class<T> clazz;
 
-    private final DataBroker dataBroker;
+    protected final DataBroker dataBroker;
 
     protected final StatNodeRegistration nodeRegistrationManager;
 
@@ -98,6 +102,8 @@ public abstract class StatAbstractListenCommit<T extends DataObject, N extends N
      */
     protected abstract InstanceIdentifier<T> getWildCardedRegistrationPath();
 
+    protected abstract void processDataChange(Collection<DataTreeModification<T>> changes);
+
     @Override
     public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
         Preconditions.checkNotNull(changes, "Changes must not be null!");
@@ -107,6 +113,7 @@ public abstract class StatAbstractListenCommit<T extends DataObject, N extends N
          * Latest read transaction will be allocated on another read using readLatestConfiguration
          */
         currentReadTxStale = true;
+        processDataChange(changes);
     }
 
     @SuppressWarnings("unchecked")
@@ -128,6 +135,7 @@ public abstract class StatAbstractListenCommit<T extends DataObject, N extends N
     @Override
     public void cleanForDisconnect(final InstanceIdentifier<Node> nodeIdent) {
         mapNodesForDelete.remove(nodeIdent);
+        removedDataBetweenStatsCycle.remove(nodeIdent);
     }
 
     @Override
index 5e8fd252a60f77f871365bd9f131516cf289b0ea..49068c71611b4dccf6f79be23168359438c9487e 100644 (file)
@@ -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<Flow, Openday
         tx.merge(LogicalDatastoreType.OPERATIONAL, tableRef, tableNew);
     }
 
+    protected void processDataChange(Collection<DataTreeModification<Flow>> changes) {
+        if (!changes.isEmpty()) {
+            for (DataTreeModification<Flow> dataChange : changes) {
+                if (dataChange.getRootNode().getModificationType() == DataObjectModification.ModificationType.DELETE) {
+                    final InstanceIdentifier<Node> 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<Flow, Openday
 
         final InstanceIdentifier<FlowCapableNode> 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<Flow> 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<FlowCapableNode> fNode;
         try {
             fNode = tx.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
@@ -259,14 +292,39 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
         for (final FlowAndStatisticsMapList flowStat : list) {
             final TableKey tableKey = new TableKey(flowStat.getTableId());
             final TableFlowUpdateState tableState = nodeState.getTable(tableKey, tx);
-            tableState.reportFlow(flowStat,tx);
+            Flow removedConfigFlow = getFlowIfRemoved(flowStat, deletedFlows);
+            if (removedConfigFlow == null) {
+                tableState.reportFlow(flowStat,tx, false);
+            } else {
+                deletedFlows.remove(removedConfigFlow);
+                tableState.reportFlow(flowStat,tx, true);
+            }
         }
 
+        if (deletedFlows != null ) {
+            deletedFlows.clear();
+        }
         for (final TableFlowUpdateState table : nodeState.getTables()) {
             table.removeUnreportedFlows(tx);
         }
     }
 
+    private Flow getFlowIfRemoved(FlowAndStatisticsMapList flowStat, ArrayList<Flow> 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<Flow, Openday
                             //flowHashId.getKey() too verbose for standard log.
                             if(LOG.isDebugEnabled()) {
                                 final FlowId currData = flowIdByHash.get(flowHashId.getKey());
-                                LOG.debug("flow hashing hit a duplicate for {} -> {}. 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<Flow, Openday
             }
         }
 
-        private FlowKey getFlowKeyAndRemoveHash(final FlowHashIdMapKey key) {
+        private FlowKey getFlowKeyByHash(final FlowHashIdMapKey key) {
             final FlowId ret = flowIdByHash.get(key);
             if(ret != null) {
-                flowIdByHash.remove(key);
                 return new FlowKey(ret);
             }
             return null;
@@ -422,16 +481,20 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
             return flowIdByHash;
         }
 
-        void reportFlow(final FlowAndStatisticsMapList flowStat, final ReadWriteTransaction trans) {
+        void reportFlow(final FlowAndStatisticsMapList flowStat,
+                        final ReadWriteTransaction trans,
+                        boolean wasRemoved) {
             ensureTableFowHashIdMapping(trans);
             final FlowHashIdMapKey hashingKey = new FlowHashIdMapKey(buildFlowIdOperKey(flowStat));
-            FlowKey flowKey = getFlowKeyAndRemoveHash(hashingKey);
-            if (flowKey == null) {
+            FlowKey flowKey = getFlowKeyByHash(hashingKey);
+            if (flowKey == null || wasRemoved) {
                 flowKey = searchInConfiguration(flowStat, trans);
                 if ( flowKey == null) {
                     flowKey = makeAlienFlowKey();
                 }
                 updateHashCache(trans,flowKey,hashingKey);
+            } else {
+                flowIdByHash.remove(hashingKey);
             }
             final FlowBuilder flowBuilder = new FlowBuilder(flowStat);
             flowBuilder.setKey(flowKey);
index b4eaa0893fbbf09563065a9d2d90f43e05198d8f..278b5486b51ce3d8b30dc2709c4840422cbfbb0c 100644 (file)
@@ -9,11 +9,14 @@
 package org.opendaylight.openflowplugin.applications.statistics.manager.impl;
 
 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.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;
@@ -25,6 +28,7 @@ import org.opendaylight.openflowplugin.applications.statistics.manager.Statistic
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager.StatDataStoreOperation;
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager.StatDataStoreOperation.StatsManagerOperationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 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.group.statistics.rev131111.GroupDescStatsUpdated;
@@ -90,6 +94,11 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                 .augmentation(FlowCapableNode.class).child(Group.class);
     }
 
+    @Override
+    protected void processDataChange(Collection<DataTreeModification<Group>> changes) {
+        //NO-OP
+    }
+
     @Override
     public void onGroupDescStatsUpdated(final GroupDescStatsUpdated notification) {
         final TransactionId transId = notification.getTransactionId();
index 20eb166586c81acce14f5f2e9dd487f2c85277ce..58b57b78912b61339db4ccced43bcb126b223ea2 100644 (file)
@@ -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<Meter, Opend
                 .augmentation(FlowCapableNode.class).child(Meter.class);
     }
 
+    @Override
+    protected void processDataChange(Collection<DataTreeModification<Meter>> changes) {
+        //NO-OP
+    }
+
     @Override
     protected OpendaylightMeterStatisticsListener getStatNotificationListener() {
         return this;
index db980dc1ee1a29d618a7a4e1ada2953cfd5eed66..cdfb8ced88426d026dc5d0cb24235efcb193e2f5 100644 (file)
@@ -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<Queue, Opend
             .augmentation(FlowCapableNodeConnector.class).child(Queue.class);
     }
 
+    @Override
+    protected void processDataChange(Collection<DataTreeModification<Queue>> changes) {
+        //NO-OP
+    }
+
     @Override
     public void onQueueStatisticsUpdate(final QueueStatisticsUpdate notification) {
         final TransactionId transId = notification.getTransactionId();
index 122ffd068044c6672fa6fe54d3a0bfee27c05ea2..2eaac49f54a2cbc902ede9c9dd8b1a4816479e10 100644 (file)
@@ -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;
index e29980894325628d1704ea496f4b17c8138da4e0..056592a4890b3b0fb9305251bbba6d87636bb0c4 100644 (file)
@@ -100,8 +100,42 @@ public enum ActionPath implements AugmentationPath {
      *    |  |           +--ro (action)?
      * </pre>
      */
-    GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION(null);
-    
+    GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION(null),
+    /**
+     * openflowplugin-extension-general.yang
+     * <pre>
+     * 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)?
+     * </pre>
+     */
+    RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION(null),
+    /**
+     * openflowplugin-extension-general.yang
+     * <pre>
+     * 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)?
+     * </pre>
+     */
+    RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION(null);
+
     private final InstanceIdentifier<Extension> iid;
 
     private ActionPath(InstanceIdentifier<Extension> iid) {
index 33fdde2509e7f0da0c575e2c8e621e0a64b72860..8ee4ebe2274d2c9c9172857be5f225515255ffe3 100644 (file)
@@ -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);
         }
index 3c8a7e4248e985c14230503c25e1438bac1d5646..92d9622514d7c7f94bf3ab81a6be77deb23a7620 100644 (file)
@@ -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);
         }
index 9bc8f21ead4f9ad009664d1a9bccf0f69d12b871..47ce802ea3c87d2023081f3d164f5955dde6d934 100644 (file)
@@ -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);
         }
index 247946f9c8cf11054a51257bdd3a0dc917bc8401..cc7f8b7c1e694c3e56179e0bbaf2c6251d76e0c5 100644 (file)
@@ -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);
         }
index 054b23b76676c46e1156e1d9c5bf7a1d1bcd91e5..55f3f32c203a693a23866c2baaa638ebace1c866 100644 (file)
@@ -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);
         }
index 0480bd607ea256c198af82053ea909f60613544c..1f5950a61c4f4a7b1e82c570a0133a5712a7cd11 100644 (file)
@@ -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);
         }
index b8ac8934b2b6519788124e7243a961a76ed81ee1..83ae5ac91216253d0e107bb4ccab88d2f3185898 100644 (file)
@@ -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);
         }
index 32766c46a028d5ebc8458632d49d98b0221121f0..d6ecfe12da333d7e334012a52bd875ea38738578 100644 (file)
@@ -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);
         }
index 2dd71c98296f8f70e1420b75e6be70ddcf4320ef..838271d15ba7e38b0e2b68d11a9da0c317dd22b1 100644 (file)
@@ -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);
         }
index 49befee900812f4c6180a66d71770c5c05e91aae..b27fac6270de545e60c4e7323a323f89f5e925ee 100644 (file)
@@ -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);
         }
index a6b16c2197df13645a359b9779497963ed84f393..4853a724d25d40780c46b06ff7223c4a0476f82c 100644 (file)
@@ -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;
+        }
+    }
 }
index 0b4eb8a60d735ced42daa35898b4210e6ae4a874..db0ce9774956e6170578154007b68ab5c26725d5 100644 (file)
@@ -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
index 16571788d3e2ae58148e115c25469a980c26cd0e..aa3bab2bf0ef5ed949c92b1550c92225df85f005 100644 (file)
@@ -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
index d7b74f972b458c188491d74075231719d19f78c0..6018fff1603027a812f329561fc2f998a17194d5 100644 (file)
@@ -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
index 693f554b22b611acca7c3e77769aae1e58d5b1bb..ced377693784578b6f1873ca56cf963f36eb0389 100644 (file)
@@ -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
index 789dcee0cca3fb14ddddc28212de5b6a20dc59ef..7982d7a7a542f39b07cd4b07fa2b97c19ae11000 100644 (file)
@@ -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
index 68bb84fb5ab7541d7e462d73b5bd8a5fb69ffe71..b5b66113dce2bbf683311bb5fdbaeed35bdc1354 100644 (file)
@@ -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
index 8d142e35b6fd1d7560cb2fb26b36a95438c5ae1b..a0ac194039584ea07f114d3eb79fcd0e3a6e94d2 100644 (file)
@@ -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
index 9de9cb7215173d72f6cf923efc0d4ca66986c6c8..ad70cda6016cce94aba516361bc3b024438ccd38 100644 (file)
@@ -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 {
index 4cabb74ea55cd81e6e6c7a6a15de8c78b79e06df..2fe3c117edbac23f8fc4629303295d568b1b9d85 100644 (file)
@@ -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;
     }
index bd05be9e448d85ffa8275296aec32b61a672943e..5fcd1b9fa70107539f4b3ddb1cf139c37903854a 100644 (file)
@@ -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<Void> stopClusterServices(boolean connectionInterrupted) {
+    default ListenableFuture<Void> stopClusterServices() {
         return Futures.immediateFailedFuture(new RejectedExecutionException("Cannot stop abstract services, check implementation of cluster services"));
     }
 
index b42c9d1a5dc7c9ab96cda02f4013914e09c5f652..63830b4951031968695145d24251193fad34f135 100644 (file)
@@ -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<String,Object> props);
 
-    void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider);
-
     void setSkipTableFeatures(boolean skipTableFeatures);
 
     void setBasicTimerDelay(long basicTimerDelay);
index b4e0b098fd496158c3774744a1bf70001d37e9a5..b5aa65fb614fde450934fa9382f2478eb6253f0f 100644 (file)
@@ -145,5 +145,11 @@ public interface DeviceContext extends
      * @return listenable future from sal role service
      */
     ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
+
+    void sendNodeAddedNotification();
+
+    void sendNodeRemovedNotification();
+
+    void cleanupDeviceData();
 }
 
index 9698c2551562d7ac968ebe5a50f82dee9e35286d..d55908b211b78f750c94a31e1d91179cde40a882 100644 (file)
@@ -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
index 931aaf0cc14fa79fecffb351706dc57ce3bd7b7f..57608463dbb8f0c45550b9904401b9e153a9681d 100644 (file)
@@ -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;
index bc770118636e9759ac67ec2a909aef052e702b41..74944b00e6bc054264dc8a75ea136bd7561e4d4d 100644 (file)
@@ -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());
index 08ccb34e2399e42eb3d6044dd6dae7cee41ed52d..b3953549589aa50163d7d62a15e7d03ad6a3da17 100644 (file)
@@ -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<SwitchConnectionProvider> 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);
 
index 302deb93e5c1a720630427708f71f5c79d4a84f9..f87bbaa8106762139d9e20a6ff4e6c72d32bce2d 100644 (file)
@@ -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<Void> stopClusterServices(boolean connectionInterrupted) {
+    public ListenableFuture<Void> stopClusterServices() {
         final ListenableFuture<Void> deactivateTxManagerFuture = initialized
                 ? transactionChainManager.deactivateTransactionManager()
                 : Futures.immediateFuture(null);
 
+        final boolean connectionInterrupted =
+                this.getPrimaryConnectionContext()
+                        .getConnectionState()
+                        .equals(ConnectionContext.CONNECTION_STATE.RIP);
         if (!connectionInterrupted) {
-            final ListenableFuture<Void> makeSlaveFuture = Futures.transform(makeDeviceSlave(), new Function<RpcResult<SetRoleOutput>, Void>() {
-                @Nullable
-                @Override
-                public Void apply(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
-                    return null;
-                }
-            });
-
-            Futures.addCallback(makeSlaveFuture, new FutureCallback<Void>() {
-                @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<Void, Void>() {
-                @Override
-                public ListenableFuture<Void> 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<Void, Void>() {
-                @Override
-                public ListenableFuture<Void> 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
index d88cb1c359489f4ceb7f40a977c29bd5411f1c0f..3595e6af9446389b62fea74afd381c278c71adb1 100644 (file)
@@ -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<DeviceInfo, DeviceContext> deviceContexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceInfo, DeviceContext> removeddeviceContexts = new ConcurrentHashMap<>();
     private final ConcurrentMap<DeviceInfo, LifecycleService> 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.<Node>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.<Node>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<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
+        return removeDeviceFromOperationalDS(deviceInfo.getNodeInstanceIdentifier(), deviceInfo.getLOGValue());
+    }
+
+    private CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(
+            final KeyedInstanceIdentifier<Node, NodeKey> 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<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
 
         Futures.addCallback(delFuture, new FutureCallback<Void>() {
             @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<RpcResult<SetRoleOutput>>() {
             @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);
+            }
+        }
+    }
 }
index 7522fe54b08f6c1d8339a449e3d4cb2b3dbe3e95..c4ac4c7d6335e8b4f8d3f01010b5ad18e56fc1aa 100644 (file)
@@ -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<DeviceRemovedHandler> 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<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
-    private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
 
 
     @Override
@@ -57,17 +58,12 @@ public class LifecycleServiceImpl implements LifecycleService {
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
-        final boolean connectionInterrupted =
-                this.deviceContext
-                        .getPrimaryConnectionContext()
-                        .getConnectionState()
-                        .equals(ConnectionContext.CONNECTION_STATE.RIP);
 
         // Chain all jobs that will stop our services
         final List<ListenableFuture<Void>> 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<List<Void>, 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();
index 01f7178e2f3cb656f92dd08ec4d3e0c55ab64a0d..4115e8b5aa4e229867cb290407be1079fd92de0b 100644 (file)
@@ -51,23 +51,24 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry {
     private final DataBroker dataBroker;
     private final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier;
     private final List<ListenableFuture<List<Optional<FlowCapableNode>>>> lastFillFutures = new ArrayList<>();
+    private final Consumer<Flow> flowConsumer;
 
-    // Specifies what to do with flow read from datastore
-    private final Consumer<Flow> 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<Node, NodeKey> instanceIdentifier) {
+    public DeviceFlowRegistryImpl(final short version, final DataBroker dataBroker, final KeyedInstanceIdentifier<Node, NodeKey> 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<FlowRegistryKey, FlowDescriptor> 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
+}
index 889e30a2c21f606852e154ce7ca14394973ee74b..a691b60ba2516d8e0e30129c00834f34b503cb22 100644 (file)
@@ -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
index 6953784a3f72f6825f29a1d696bc874e480c44d9..f794d850511c98509dc4e8a5f36c8305038b79bb 100644 (file)
@@ -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<Void> stopClusterServices(boolean connectionInterrupted) {
+    public ListenableFuture<Void> stopClusterServices() {
         if (CONTEXT_STATE.TERMINATION.equals(getState())) {
             return Futures.immediateCancelledFuture();
         }
index 9b1c0e729158ba831b4fe13ce4dcd379f13501fe..da8d74275dd45956d9b493e303366984211b7320 100644 (file)
@@ -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<List<MultipartReply>> {
     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<FlowCapableNode> fcNodeOpt;
+    private AtomicBoolean virgin = new AtomicBoolean(true);
+    private AtomicBoolean finished = new AtomicBoolean(false);
 
     public MultipartRequestOnTheFlyCallback(final RequestContext<List<MultipartReply>> context,
                                             final Class<?> requestType,
@@ -70,64 +72,57 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
 
     @Override
     public void onSuccess(final OfHeader result) {
+
         if (result == null) {
             LOG.info("Ofheader was null.");
-            if (!finished) {
+            if (!finished.getAndSet(true)) {
                 endCollecting();
                 return;
             }
-        } else if (finished) {
+        } else if (finished.get()) {
             LOG.debug("Unexpected multipart response received: xid={}, {}", result.getXid(), result.getImplementedInterface());
             return;
         }
 
         if (!(result instanceof MultipartReply)) {
-            LOG.info("Unexpected response type received {}.", result.getClass());
-            final RpcResultBuilder<List<MultipartReply>> rpcResultBuilder =
-                    RpcResultBuilder.<List<MultipartReply>>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<List<MultipartReply>> rpcResultBuilder =
+                        RpcResultBuilder.<List<MultipartReply>>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<? extends DataObject> multipartDataList = multipartReplyTranslator.translate(
                     deviceInfo.getDatapathId(), deviceInfo.getVersion(), singleReply);
-            final Iterable<? extends DataObject> allMultipartData = multipartDataList;
+            final Iterable<FlowsStatisticsUpdate> allMultipartData = (Iterable<FlowsStatisticsUpdate>) multipartDataList;
 
-            //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats
-            ListenableFuture<Void> 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<Void, Void>() {
-
-                @Override
-                public Void apply(final Void input) {
-                    StatisticsGatheringUtils.writeFlowStatistics((Iterable<FlowsStatisticsUpdate>) 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<List<MultipartReply>> rpcResult = RpcResultBuilder.success(Collections.<MultipartReply>emptyList()).build();
         spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
-        txFacade.submitTransaction();
         setResult(rpcResult);
-        finished = true;
+        txFacade.submitTransaction();
     }
 }
index 5f032a70435daedf563c3690e012d9ca0d7e507f..5a4ed71f75fa31bd683ccf159873f79946e18a8a 100644 (file)
@@ -75,7 +75,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
 
     @Override
     public Future<RpcResult<AddFlowOutput>> addFlow(final AddFlowInput input) {
-        final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input);
+        final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input);
         final ListenableFuture<RpcResult<AddFlowOutput>> 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
+}
index eab57c27958dd96bb539a608fb38a525553115a9..3002b8e632d83e53bb23b5d0f6f6376c92605cf0 100644 (file)
@@ -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<Void> stopClusterServices(boolean connectionInterrupted) {
+    public ListenableFuture<Void> stopClusterServices() {
         if (CONTEXT_STATE.TERMINATION.equals(getState())) {
             return Futures.immediateCancelledFuture();
         }
index 3893b9f391ef6ccef71bff37be4aa56fbd742a1a..bb789b62712adcb86e0667410cb2bfd40a68dcac 100644 (file)
@@ -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<Void> deleteFuture
-                = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo,
-                flowRegistry, txFacade);
+                = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo, flowRegistry, txFacade);
         return Futures.transform(deleteFuture, (Function<Void, Boolean>) 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<Optional<FlowCapableNode>, Void>) flowCapNodeOpt -> {
-                if (flowCapNodeOpt.isPresent()) {
-                    for (final Table tableData : flowCapNodeOpt.get().getTable()) {
-                        final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
-                        final InstanceIdentifier<Table> 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.<Flow>emptyList()).build();
+                            final InstanceIdentifier<Table> iiToTable
+                                    = flowCapableNodePath.child(Table.class, tableData.getKey());
+                            txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
+                        }
                     }
+                    readTx.close();
+                    return Futures.immediateFuture(null);
+                });
+    }
+
+    public static Optional<FlowCapableNode> deleteAllKnownFlows(final DeviceInfo deviceInfo,
+                                                             final TxFacade txFacade) {
+        final InstanceIdentifier<FlowCapableNode> flowCapableNodePath
+                = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+        final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
+                LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
+
+        try {
+            Optional<FlowCapableNode> fcNodeOpt = flowCapableNodeFuture.get();
+            if ( fcNodeOpt != null && fcNodeOpt.isPresent()){
+                for (final Table tableData : flowCapableNodeFuture.get().get().getTable()) {
+                    final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
+                    final InstanceIdentifier<Table> 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(
index 35a0d73778b3b4ab96f40a552cfc840500cbb7ec..06dc64de2688f7183a14cf35543128e70912402d 100644 (file)
@@ -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);
                 }
             }
index adbd1e9736c72165540269734e8627d7222d00e2..a106ad93e57f9a16f74e1d6a0b7058c2863e27b2 100644 (file)
@@ -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);
     }
 }
index eb9ff12296554045022cffdf270f6c08fc0be45f..86d4c9c3a40983334157f3a031b8bb1bd69f7787 100644 (file)
@@ -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<FlowRemoved, org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved> {
     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<FlowRemoved, org
                 .setPriority(input.getPriority())
                 .setTableId(translateTableId(input));
 
+        if(Objects.nonNull(input.getReason())) {
+            flowRemovedBld.setReason(translateReason(input));
+        }
+
         return flowRemovedBld.build();
     }
 
@@ -64,4 +72,22 @@ public class FlowRemovedTranslator implements MessageTranslator<FlowRemoved, org
     protected Short translateTableId(FlowRemoved flowRemoved) {
         return flowRemoved.getTableId().getValue().shortValue();
     }
+
+
+    private RemovedFlowReason translateReason(FlowRemoved removedFlow) {
+        logger.debug("--Entering translateReason within FlowRemovedTranslator with reason:{} " + removedFlow.getReason());
+        switch (removedFlow.getReason()) {
+            case OFPRRIDLETIMEOUT:
+                return RemovedFlowReason.OFPRRIDLETIMEOUT;
+            case OFPRRHARDTIMEOUT:
+                return RemovedFlowReason.OFPRRHARDTIMEOUT;
+            case OFPRRDELETE:
+                return RemovedFlowReason.OFPRRDELETE;
+            case OFPRRGROUPDELETE:
+                return RemovedFlowReason.OFPRRGROUPDELETE;
+            default:
+                logger.debug("The flow is being deleted for some unknown reason  ");
+                return RemovedFlowReason.OFPRRDELETE;
+        }
+    }
 }
index 8c3b48e0fdec1fa10294f57c90eb9f08826fb248..7b005a7ae3e3f5ccb78bcc5663e84dcb7c8ccc9c 100644 (file)
@@ -8,8 +8,10 @@
 
 package org.opendaylight.openflowplugin.impl.util;
 
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -45,7 +47,7 @@ public final class MatchComparatorFactory {
              * Comparation by whole object
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 return (statsMatch == null) == (storedMatch == null);
             }
         };
@@ -57,7 +59,7 @@ public final class MatchComparatorFactory {
              * Comparation by VLAN
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -79,7 +81,7 @@ public final class MatchComparatorFactory {
              * Comparation by tunnel
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -101,7 +103,7 @@ public final class MatchComparatorFactory {
              * Comparation by protocol fields
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -123,7 +125,7 @@ public final class MatchComparatorFactory {
              * Comparation by metadata
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -145,7 +147,7 @@ public final class MatchComparatorFactory {
              * Comparation by layer4
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -167,7 +169,7 @@ public final class MatchComparatorFactory {
              * Comparation by layer3
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -189,7 +191,7 @@ public final class MatchComparatorFactory {
              * Comparation by Ip
              */
             @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+            public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
                 if (storedMatch == null) {
                     return false;
                 }
@@ -205,13 +207,39 @@ public final class MatchComparatorFactory {
         };
     }
 
+
+    /**
+     * Converts both ports in node connector id format to number format and compare them
+     *
+     * @param version openflow version
+     * @param left first object to compare
+     * @param right second object to compare
+     * @return true if equal
+     */
+    private static boolean arePortNumbersEqual(short version, NodeConnectorId left, NodeConnectorId right) {
+        final OpenflowVersion ofVersion = OpenflowVersion.get(version);
+
+        final Long leftPort = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, left);
+        final Long rightPort = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, right);
+
+        if (leftPort == null) {
+            if (rightPort != null) {
+                return false;
+            }
+        } else if (!leftPort.equals(rightPort)) {
+            return false;
+        }
+
+        return true;
+    }
+
     public static SimpleComparator<Match> createInPort() {
         return new SimpleComparator<Match>() {
             /**
              * 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<Match> matchComp : MATCH_COMPARATORS) {
-            if (!matchComp.areObjectsEqual(statsMatch, storedMatch)) {
+            if (!matchComp.areObjectsEqual(version, statsMatch, storedMatch)) {
                 return false;
             }
         }
index 456a731687ccdbcc688018c3a9bc3424d3a01cd7..c6b317404245dbd8d1b2d40b34189895a2a05ffe 100644 (file)
@@ -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;
index 55583e9c54dd88e2e0566fad17253534c4ac4d02..dfcea9b27739d945dd8c2b84c7e206761a331977 100644 (file)
@@ -10,6 +10,6 @@ package org.opendaylight.openflowplugin.impl.util;
 
 public interface SimpleComparator<T> {
 
-    boolean areObjectsEqual(T obj1, T obj2);
+    boolean areObjectsEqual(short version, T obj1, T obj2);
 
-}
\ No newline at end of file
+}
index 20b907b41694bfb03e5d1d6040eddc08708016a0..976efaabee28c5b988d888fe4959faa73f1d2503 100644 (file)
@@ -6,4 +6,6 @@
 
   <service ref="ofPluginProviderFactory" interface="org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProviderFactory"
           odl:type="default"/>
-</blueprint>
\ No newline at end of file
+
+  <odl:action-provider interface="org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService"/>
+</blueprint>
index dc619d61fc0f707f2422d9a200b2b81b9bfc1216..c6fbf45dcca0e02fcf701511a34fb58850f739c9 100644 (file)
@@ -90,6 +90,7 @@ public class OpenFlowPluginProviderImplTest {
         provider.setNotificationProviderService(notificationService);
         provider.setSwitchConnectionProviders(Lists.newArrayList(switchConnectionProvider));
         provider.setClusteringSingletonServicesProvider(clusterSingletonServiceProvider);
+        provider.setEntityOwnershipServiceProvider(entityOwnershipService);
     }
 
     @After
index 8eb0f9ff7d19fcbf23a6ec20330339a48a60f1fd..6f0bcb0ff975b1f71b1db089d86de1f80ea2e3ac 100644 (file)
@@ -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<? extends MultipartRequestBody> 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
index 2af535ac9386763edd4d7723f366fbae5b85290f..e5a3167bc5ab581e4ad722f752e958c669d2525c 100644 (file)
@@ -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);
 
index 33e54b4d7c313e1bab26b678954fc151a8c95a3c..17abab3ea32242b59b98c6f34a0415a90a985a79 100644 (file)
@@ -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<Node, NodeKey> 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);
index 7d02cdb2e14fd7bd25e47692ff78fc5573870637..4cf06d4eb4bc544ca08bfb00f29f871596f1290b 100644 (file)
@@ -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
index dafa7ca27e233202e06d2f64b3e591fbd66dead1..250d13615c08833ec81a3b51801357d4ef807639 100644 (file)
@@ -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<FlowRegistryKey, FlowDescriptor> 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
+}
index 26313fc95f9e0db2634bf0fb34e6090d6a8ef172..35e08e6cdf9f5171f915d95bb17c1e7736024597 100644 (file)
@@ -71,8 +71,8 @@ public class FlowRegistryKeyFactoryTest {
 
         HashSet<FlowRegistryKey> 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);
index 098ef4dd866e6061fae6f2ad3590a0f16a78dfa5..5d15eff5cd7e86192ff42eeafd5da300ab46c6b5 100644 (file)
@@ -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.<Table> emptyList());
         final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
+
         final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures.immediateCheckedFuture(flowNodeOpt);
-        when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
+        final CheckedFuture<Optional<FlowCapableNode>, 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<List<MultipartReply>>(DUMMY_XID) {
@@ -234,7 +238,10 @@ public class MultipartRequestOnTheFlyCallbackTest {
         final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
         final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures
                 .immediateCheckedFuture(flowNodeOpt);
-        when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
+        final CheckedFuture<Optional<FlowCapableNode>, 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.<MatchEntry>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<FlowCapableNode> 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<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures
+                .immediateCheckedFuture(flowNodeOpt);
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture);
 
-        final RpcResult<List<MultipartReply>> 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.<InstanceIdentifier>any(), Matchers.<DataObject>any());
+        multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build());
+        final InstanceIdentifier<Table> 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.<Table> 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.<InstanceIdentifier> any(), Matchers.<DataObject> any());
     }
 }
index fafa4df3f810fa407fd820673d42c508a7f54764..92180d798ab28ea05c0d2e527b9bcd72f292d368 100644 (file)
@@ -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);
index 65abd670d9027b382a4a232ae225872b6b3f6f38..461c92c5df90fafa27732cc406480f9ccd5dde73 100644 (file)
@@ -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.<RequestContext<List<MultipartReply>>>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 (file)
index 0000000..5c29fc8
--- /dev/null
@@ -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<bytes.length;i++) {
+            int mask = maskBytes[i];
+            assertEquals(bytes[i],mask);
+        }
+    }
+
+    @Test
+    public void isArbitraryBitMaskTest() {
+        boolean arbitraryBitMask;
+        arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {1,1,1,1});
+        assertEquals(arbitraryBitMask,true);
+        arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,-1,-1});
+        assertEquals(arbitraryBitMask,false);
+        arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,0,-1});
+        assertEquals(arbitraryBitMask,true);
+        arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(null);
+        assertEquals(arbitraryBitMask,false);
+    }
+
+    @Test
+    public void createPrefixTest() {
+        Ipv4Address ipv4Address = new Ipv4Address("1.1.1.1");
+        byte [] byteMask = new byte[] {-1,-1,-1,-1};
+        Ipv4Prefix ipv4Prefix = MatchComparatorHelper.createPrefix(ipv4Address,byteMask);
+        assertEquals(ipv4Prefix,new Ipv4Prefix("1.1.1.1/32"));
+        String nullMask = "";
+        Ipv4Prefix ipv4PrefixNullMask = MatchComparatorHelper.createPrefix(ipv4Address,nullMask);
+        assertEquals(ipv4PrefixNullMask,new Ipv4Prefix("1.1.1.1/32"));
+        Ipv4Prefix ipv4PrefixNoMask = MatchComparatorHelper.createPrefix(ipv4Address);
+        assertEquals(ipv4PrefixNoMask,new Ipv4Prefix("1.1.1.1/32"));
+    }
+
+    @Test
+    public void layer3MatchEqualsIpv6ArbitraryMaskTest(){
+        final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+        final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+        assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+        statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6:7:8/16"));
+        storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+        storedBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF:0000:0000:0000:0000:0000:0000:0000"));
+        statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6:7:8/32"));
+        storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+        storedBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF:FFFF::"));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+    }
+
+
+    @Test
+    public void layer3MatchEqualsIpv6ArbitraryMaskRandomTest() {
+        final Ipv6MatchArbitraryBitMaskBuilder statsBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+        final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+        assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+        statsBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1::8"));
+        statsBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+        storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:92:93:94:95:96:97:8"));
+        storedBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+        statsBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1::8"));
+        statsBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+        storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:92:93:94:95:96:97:8"));
+        storedBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+    }
+
+    @Test
+    public void layer3MatchEqualsIpv6ArbitraryMaskEqualsNullTest() {
+        final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+        final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+        assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+        statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6:7:8/128"));
+        storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+        statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6::/128"));
+        storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6::"));
+        assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+    }
+
+    @Test
+    public void layer3MatchEqualsIpv6ArbitraryEmptyBitMaskTest(){
+        final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+        final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+        assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+        statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6:7:8/128"));
+        storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+        statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6::/128"));
+        storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6::"));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+        assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+    }
+}
index 493771c3a1e497dd279e7a4c2a7ec2fe60b51089..6a5298b2580ebe0e64694ce7d43d7e87ca111d9c 100644 (file)
@@ -14,6 +14,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Objects;
 import java.util.concurrent.CopyOnWriteArrayList;
 import org.opendaylight.openflowjava.util.ByteBufUtils;
 import org.opendaylight.openflowplugin.api.OFConstants;
@@ -34,7 +35,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 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.flow.service.rev130819.SwitchFlowRemovedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedReasonFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedFlowReason;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
@@ -63,7 +64,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.PbbBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowRemovedReason;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpOp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSha;
@@ -147,6 +147,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.matc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpSrcCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanPcpCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelIpv4Dst;
@@ -190,14 +191,10 @@ public class FlowRemovedTranslator implements IMDMessageTranslator<OfHeader, Lis
             salFlowRemoved.setHardTimeout(ofFlow.getHardTimeout());
             salFlowRemoved.setPacketCount(ofFlow.getPacketCount());
             salFlowRemoved.setByteCount(ofFlow.getByteCount());
-            RemovedReasonFlags removeReasonFlag = new RemovedReasonFlags(
-                    FlowRemovedReason.OFPRRDELETE.equals(ofFlow.getReason()),
-                    FlowRemovedReason.OFPRRGROUPDELETE.equals(ofFlow.getReason()),
-                    FlowRemovedReason.OFPRRHARDTIMEOUT.equals(ofFlow.getReason()),
-                    FlowRemovedReason.OFPRRIDLETIMEOUT.equals(ofFlow.getReason())
-            );
 
-            salFlowRemoved.setRemovedReason(removeReasonFlag);
+            if(Objects.nonNull(ofFlow.getReason())) {
+                salFlowRemoved.setRemovedReason(translateReason(ofFlow));
+            }
 
             OpenflowVersion ofVersion = OpenflowVersion.get(sc.getPrimaryConductor().getVersion());
             org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch = ofFlow
@@ -220,7 +217,22 @@ public class FlowRemovedTranslator implements IMDMessageTranslator<OfHeader, Lis
             return Collections.emptyList();
         }
     }
-
+    private RemovedFlowReason translateReason(FlowRemoved removedFlow) {
+        LOG.debug("--Entering translateReason within FlowRemovedTranslator with reason:{} " + removedFlow.getReason());
+        switch (removedFlow.getReason()) {
+            case OFPRRIDLETIMEOUT:
+                return RemovedFlowReason.OFPRRIDLETIMEOUT;
+            case OFPRRHARDTIMEOUT:
+                return RemovedFlowReason.OFPRRHARDTIMEOUT;
+            case OFPRRDELETE:
+                return RemovedFlowReason.OFPRRDELETE;
+            case OFPRRGROUPDELETE:
+                return RemovedFlowReason.OFPRRGROUPDELETE;
+            default:
+                LOG.debug("The flow being default and hence deleting it ");
+                return RemovedFlowReason.OFPRRDELETE;
+        }
+    }
 
     public Match fromMatch(final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch,
                            final BigInteger datapathid, final OpenflowVersion ofVersion) {
index ee4216f69c7364911f296211a33f2ff0c4dfb5c8..336f101cbd916244d1a2d1e0a41a4a6a7d71ee2a 100644 (file)
@@ -14,6 +14,7 @@ import java.io.IOException;
 import java.math.BigInteger;\r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
+import java.util.Collections;\r
 import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.Map;\r
@@ -28,16 +29,20 @@ import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator
 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;\r
 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;\r
 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;\r
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;\r
 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl;\r
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContextOFImpl;\r
 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;\r
 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;\r
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceivedBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;\r
 import org.opendaylight.yangtools.yang.binding.DataObject;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
@@ -167,23 +172,12 @@ public class PacketInV10TranslatorTest {
         List<DataObject> salPacketIn = packetInV10Translator.translate(cookie,\r
                 sessionContextOFImpl, message);\r
 \r
-        //TODO: rewrite to object and involve object comparison in Assert\r
-        String expectedString = "[PacketReceived [_ingress=NodeConnectorRef [_value=KeyedInstanceIdentifier"\r
-                + "{targetType=interface org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector,"\r
-                + " path=[org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes,"\r
-                + " org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node["\r
-                + "key=NodeKey [_id=Uri [_value=openflow:"\r
-                + datapathId.toString()\r
-                + "]]],"\r
-                + " org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector["\r
-                + "key=NodeConnectorKey [_id=Uri [_value=openflow:"\r
-                + datapathId.toString()\r
-                + ":"\r
-                + message.getInPort().toString()\r
-                + "]]]]}], _packetInReason=class org.opendaylight.yang.gen.v1.urn.opendaylight."\r
-                + "packet.service.rev130709.SendToController, _payload=[115, 101, 110, 100, 79, 117,"\r
-                + " 116, 112, 117, 116, 77, 115, 103, 95, 84, 69, 83, 84], augmentation=[]]]";\r
-        Assert.assertEquals(expectedString, salPacketIn.toString());\r
+        Assert.assertEquals(Collections.singletonList(new PacketReceivedBuilder()\r
+                .setIngress(InventoryDataServiceUtil.nodeConnectorRefFromDatapathIdPortno(datapathId, (long) message.getInPort(), OpenflowVersion.OF10))\r
+                .setPacketInReason(SendToController.class)\r
+                .setPayload(data)\r
+                .build()).toString(), salPacketIn.toString());\r
+\r
         LOG.debug("Test translate done.");\r
     }\r
 \r