Merge "Bug 4957 TxChainManager lifecycle startup cleaning"
[openflowplugin.git] / applications / statistics-manager / src / main / java / org / opendaylight / openflowplugin / applications / statistics / manager / impl / StatListenCommitFlow.java
index 9388a6bc14058bf1ba4ab02eb39230a2baea9077..63f08c79dd9d173f8c7d8069705b6db4e62ff6af 100644 (file)
@@ -8,23 +8,26 @@
 
 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.LinkedList;
 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.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.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.openflowplugin.applications.statistics.manager.impl.helper.FlowComparator;
@@ -52,8 +55,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.a
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-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.transaction.rev150304.TransactionAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
 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;
@@ -64,10 +67,6 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-
 /**
  * statistics-manager
  * org.opendaylight.openflowplugin.applications.statistics.manager.impl
@@ -89,12 +88,14 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
     private static final String ALIEN_SYSTEM_FLOW_ID = "#UF$TABLE*";
 
     private static final Integer REMOVE_AFTER_MISSING_COLLECTION = 1;
+    private static final int TRUNCATED_LOG_MESSAGE_LENGTH = 30;
 
     private final AtomicInteger unaccountedFlowsCounter = new AtomicInteger(0);
 
     public StatListenCommitFlow (final StatisticsManager manager, final DataBroker db,
-            final NotificationProviderService nps){
-        super(manager, db, nps, Flow.class);
+            final NotificationProviderService nps,
+                                 final StatNodeRegistration nrm){
+        super(manager, db, nps, Flow.class,nrm);
     }
 
     @Override
@@ -133,6 +134,9 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
                 if (( ! inputObj.isPresent()) || ( ! (inputObj.get() instanceof Table))) {
                     return;
                 }
+
+                if(!nodeRegistrationManager.isFlowCapableNodeOwner(nodeId)) { return; }
+
                 final Table table = (Table) inputObj.get();
                 final List<? extends TransactionAware> cacheNotifs = txContainer.get().getNotifications();
                 for (final TransactionAware notif : cacheNotifs) {
@@ -158,6 +162,11 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
                     }
                 }
             }
+
+            @Override
+            public UUID generatedUUIDForNode() {
+                return manager.getGeneratedUUIDForNode(getNodeIdentifier());
+            }
         });
     }
 
@@ -187,6 +196,8 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
                 if (( ! txContainer.isPresent()) || txContainer.get().getNotifications() == null) {
                     return;
                 }
+                if(!nodeRegistrationManager.isFlowCapableNodeOwner(nodeId)) { return; }
+
                 final List<FlowAndStatisticsMapList> flowStats = new ArrayList<FlowAndStatisticsMapList>(10);
                 final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class)
                         .child(Node.class, new NodeKey(nodeId));
@@ -220,6 +231,11 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
                 notifyToCollectNextStatistics(nodeIdent, transId);
             }
 
+            @Override
+            public UUID generatedUUIDForNode() {
+                return manager.getGeneratedUUIDForNode(getNodeIdentifier());
+            }
+
         });
     }
 
@@ -276,7 +292,7 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
      * FIXME: CREATE BETTER KEY - for flow (MATCH is the problem)
      */
     static String buildFlowIdOperKey(final FlowAndStatisticsMapList deviceFlow) {
-        return new StringBuffer().append(deviceFlow.getMatch())
+        return new StringBuilder().append(deviceFlow.getMatch())
                 .append(deviceFlow.getPriority()).append(deviceFlow.getCookie().getValue()).toString();
     }
 
@@ -330,8 +346,18 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
                         try {
                             flowIdByHash.put(flowHashId.getKey(), flowHashId.getFlowId());
                         } catch (final Exception e) {
-                            LOG.warn("flow hashing hit a duplicate for {} -> {}. Exception {}",
-                                    flowHashId.getKey(), flowHashId.getFlowId(), e);
+                            //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:",
+                                    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.",
+                                    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())));
+                            }
                         }
                     }
                 }
@@ -354,11 +380,12 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
             while(it.hasNext()) {
                 final Flow cfgFlow = it.next();
                 final FlowKey cfgKey = cfgFlow.getKey();
-                if(flowIdByHash.inverse().containsKey(cfgKey)) {
-                    it.remove();
-                } else if(FlowComparator.flowEquals(flowStat, cfgFlow)) {
-                    it.remove();
-                    return cfgKey;
+                final FlowId cfgFlowId = cfgKey.getId();
+
+                if(! flowIdByHash.inverse().containsKey(cfgFlowId)) {
+                    if(FlowComparator.flowEquals(flowStat, cfgFlow)) {
+                        return cfgKey;
+                    }
                 }
             }
             return null;
@@ -373,7 +400,7 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
             if(localList == null) {
                 configFlows = Collections.emptyList();
             } else {
-                configFlows = new LinkedList<>(localList);
+                configFlows = new ArrayList<>(localList);
             }
         }
 
@@ -441,7 +468,7 @@ public class StatListenCommitFlow extends StatAbstractListenCommit<Flow, Openday
                 final InstanceIdentifier<Flow> flowRef = tableRef.child(Flow.class, flowKey);
                 if (nodeDeleteMap != null && flowKey.getId().getValue().startsWith(ALIEN_SYSTEM_FLOW_ID)) {
                     final Integer lifeIndex = nodeDeleteMap.get(flowRef);
-                    if (lifeIndex > 0) {
+                     if (lifeIndex != null && lifeIndex > 0) {
                         break;
                     } else {
                         nodeDeleteMap.remove(flowRef);