Merge "Bug 6110: Fixed bugs in statistics manager due to race condition." into stable...
[openflowplugin.git] / applications / statistics-manager / src / main / java / org / opendaylight / openflowplugin / applications / statistics / manager / impl / StatListenCommitGroup.java
index 574e4f9ccdfb4ef9b907ac133dc760206161ea32..278b5486b51ce3d8b30dc2709c4840422cbfbb0c 100644 (file)
@@ -9,22 +9,28 @@
 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;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager;
+import org.opendaylight.openflowplugin.applications.statistics.manager.StatNodeRegistration;
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatPermCollector.StatCapabTypes;
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
+import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager;
 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.transaction.rev131103.TransactionAware;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
@@ -62,21 +68,19 @@ import com.google.common.base.Preconditions;
  * org.opendaylight.openflowplugin.applications.statistics.manager.impl
  *
  * StatListenCommitGroup
- * Class is a NotifyListener for GroupStatistics and DataChangeListener for Config/DataStore for Group node.
+ * Class is a NotifyListener for GroupStatistics and DataTreeChangeListener for Config/DataStore for Group node.
  * All expected (registered) GroupStatistics will be builded and commit to Operational/DataStore.
- * DataChangeEven should call create/delete Group in Operational/DS
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
+ * DataTreeModification should call create/delete Group in Operational/DS
  */
 public class StatListenCommitGroup extends StatAbstractListenCommit<Group, OpendaylightGroupStatisticsListener>
                                                     implements OpendaylightGroupStatisticsListener {
 
-    private static final Logger LOG = LoggerFactory.getLogger(StatListenCommitMeter.class);
+    private static final Logger LOG = LoggerFactory.getLogger(StatListenCommitGroup.class);
 
     public StatListenCommitGroup(final StatisticsManager manager,  final DataBroker db,
-            final NotificationProviderService nps) {
-        super(manager, db, nps, Group.class);
+            final NotificationProviderService nps,
+                                 final StatNodeRegistration nrm) {
+        super(manager, db, nps, Group.class,nrm);
     }
 
     @Override
@@ -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();
@@ -126,6 +135,9 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                 if ( ! isTransactionCacheContainerValid(txContainer)) {
                     return;
                 }
+
+                if(!nodeRegistrationManager.isFlowCapableNodeOwner(nodeId)) { return; }
+
                 /* Prepare List actual Groups and not updated Groups will be removed */
                 final List<Group> existGroups = fNode.get().getGroup() != null
                         ? fNode.get().getGroup() : Collections.<Group> emptyList();
@@ -140,6 +152,11 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                 /* Notification for continue collecting statistics */
                 notifyToCollectNextStatistics(nodeIdent, transId);
             }
+
+            @Override
+            public UUID generatedUUIDForNode() {
+                return manager.getGeneratedUUIDForNode(getNodeIdentifier());
+            }
         });
     }
 
@@ -170,6 +187,10 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                 final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier
                         .create(Nodes.class).child(Node.class, new NodeKey(nodeId));
 
+                manager.registerAdditionalNodeFeature(nodeIdent, StatCapabTypes.GROUP_STATS);
+
+                if(!nodeRegistrationManager.isFlowCapableNodeOwner(nodeId)) { return; }
+
                 final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
                 for (final TransactionAware notif : cacheNotifs) {
                     if ( ! (notif instanceof GroupFeaturesUpdated)) {
@@ -190,10 +211,17 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                     if (node.isPresent()) {
                         tx.merge(LogicalDatastoreType.OPERATIONAL, nodeGroupFeatureIdent, new NodeGroupFeaturesBuilder().build(), true);
                         tx.put(LogicalDatastoreType.OPERATIONAL, groupFeatureIdent, stats);
-                        manager.registerAdditionalNodeFeature(nodeIdent, StatCapabTypes.GROUP_STATS);
+                        manager.unregisterNodeStats(nodeIdent, StatCapabTypes.GROUP_FEATURE_STATS);
+                    } else {
+                        LOG.debug("Node {} is NOT present in the operational data store",nodeId);
                     }
                 }
             }
+
+            @Override
+            public UUID generatedUUIDForNode() {
+                return manager.getGeneratedUUIDForNode(getNodeIdentifier());
+            }
         });
     }
 
@@ -235,6 +263,9 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                 if ( ! isTransactionCacheContainerValid(txContainer)) {
                     return;
                 }
+
+                if(!nodeRegistrationManager.isFlowCapableNodeOwner(nodeId)) { return; }
+
                 final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
 
                 Optional<Group> notifGroup = Optional.absent();
@@ -252,6 +283,10 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
                     notifyToCollectNextStatistics(nodeIdent, transId);
                 }
             }
+
+            public UUID generatedUUIDForNode() {
+                return manager.getGeneratedUUIDForNode(getNodeIdentifier());
+            }
         });
     }
 
@@ -339,6 +374,7 @@ public class StatListenCommitGroup extends StatAbstractListenCommit<Group, Opend
             }
             catch (final ReadFailedException e) {
                 // NOOP - probably another transaction delete that node
+                LOG.debug("Group {} was probably deleted via other transaction. Exception {}", delGroupIdent, e);
             }
             if (delGroup.isPresent()) {
                 trans.delete(LogicalDatastoreType.OPERATIONAL, delGroupIdent);