Internal API + unit tests for packet count stats. Also stream-lined some of the...
[affinity.git] / analytics / implementation / src / main / java / org / opendaylight / affinity / analytics / internal / AnalyticsManager.java
index 8d0669270494006062e97721f51cbd6c02806327..4638594e893ef974e8cf78550b6ca0e842b96e78 100644 (file)
@@ -171,6 +171,20 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return srcHost;
     }
 
+    /* Return all protocols used between two sets */
+    protected Set<Byte> getProtocols(Set<Host> srcSet, Set<Host> dstSet) {
+        Set<Byte> protocols = new HashSet<Byte>();
+        for (Host src : srcSet) {
+            for (Host dst : dstSet) {
+                if (this.hostsToStats.get(src) != null &&
+                    this.hostsToStats.get(src).get(dst) != null) {
+                    protocols.addAll(this.hostsToStats.get(src).get(dst).getProtocols());
+                }
+            }
+        }
+        return protocols;
+    }
+
     /* Return the number of bytes transferred between two sets,
      * per-protocol (across all protocols if protocol is null).*/
     protected long getByteCount(Set<Host> srcSet, Set<Host> dstSet, Byte protocol) {
@@ -189,27 +203,40 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return byteCount;
     }
 
-    /* Return all protocols used between two sets */
-    protected Set<Byte> getProtocols(Set<Host> srcSet, Set<Host> dstSet) {
-        Set<Byte> protocols = new HashSet<Byte>();
+    /* Returns a map of protocol -> byte counts between two sets */
+    protected Map<Byte, Long> getAllByteCounts(Set<Host> srcSet, Set<Host> dstSet) {
+        Map<Byte, Long> byteCounts = new HashMap<Byte, Long>();
+        Set<Byte> protocols = getProtocols(srcSet, dstSet);
+        for (Byte protocol : protocols)
+            byteCounts.put(protocol, getByteCount(srcSet, dstSet, protocol));
+        return byteCounts;
+    }
+
+    /* Returns the packet count between two sets, per-protocol (across
+     * all protocols if protocol is null). */
+    protected long getPacketCount(Set<Host> srcSet, Set<Host> dstSet, Byte protocol) {
+        long packetCount = 0;
         for (Host src : srcSet) {
             for (Host dst : dstSet) {
                 if (this.hostsToStats.get(src) != null &&
                     this.hostsToStats.get(src).get(dst) != null) {
-                    protocols.addAll(this.hostsToStats.get(src).get(dst).getProtocols());
+                    if (protocol == null)
+                        packetCount += this.hostsToStats.get(src).get(dst).getPacketCount();
+                    else
+                        packetCount += this.hostsToStats.get(src).get(dst).getPacketCount(protocol);
                 }
             }
         }
-        return protocols;
+        return packetCount;
     }
 
-    /* Returns a map of all byte counts between two sets */
-    protected Map<Byte, Long> getAllByteCounts(Set<Host> srcSet, Set<Host> dstSet) {
-        Map<Byte, Long> byteCounts = new HashMap<Byte, Long>();
+    /* Returns a map of protocol -> packet counts between two sets */
+    protected Map<Byte, Long> getAllPacketCounts(Set<Host> srcSet, Set<Host> dstSet) {
+        Map<Byte, Long> packetCounts = new HashMap<Byte, Long>();
         Set<Byte> protocols = getProtocols(srcSet, dstSet);
         for (Byte protocol : protocols)
-            byteCounts.put(protocol, getByteCount(srcSet, dstSet, protocol));
-        return byteCounts;
+            packetCounts.put(protocol, getPacketCount(srcSet, dstSet, protocol));
+        return packetCounts;
     }
 
     /* Returns the duration of communication between two sets (max
@@ -235,6 +262,15 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return maxDuration;
     }
 
+    /* Returns a map of protocol -> (max) duration over that protocol. */
+    protected Map<Byte, Double> getAllDurations(Set<Host> srcSet, Set<Host> dstSet) {
+        Map<Byte, Double> durations = new HashMap<Byte, Double>();
+        Set<Byte> protocols = getProtocols(srcSet, dstSet);
+        for (Byte protocol : protocols)
+            durations.put(protocol, getDuration(srcSet, dstSet, protocol));
+        return durations;
+    }
+
     /* Returns the bit rate between two sets */
     protected double getBitRate(Set<Host> srcSet, Set<Host> dstSet, Byte protocol) {
         double duration = getDuration(srcSet, dstSet, protocol);
@@ -244,6 +280,7 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return (totalBytes * 8.0) / duration;
     }
 
+    /* Returns all bit rates between two sets */
     protected Map<Byte, Double> getAllBitRates(Set<Host> srcSet, Set<Host> dstSet) {
         Map<Byte, Double> bitRates = new HashMap<Byte, Double>();
         Set<Byte> protocols = getProtocols(srcSet, dstSet);
@@ -252,143 +289,87 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return bitRates;
     }
 
-    /* These are all basic getters/setters, most of which are required
-     * by IAnalyticsManager */
-    public long getByteCount(Host src, Host dst) {
-        return getByteCount(src, dst, null);
-    }
-
-    public long getByteCount(Host src, Host dst, Byte protocol) {
-        Set<Host> srcSet = new HashSet<Host>(Arrays.asList(src));
-        Set<Host> dstSet = new HashSet<Host>(Arrays.asList(dst));
-        return getByteCount(srcSet, dstSet, protocol);
-    }
-
-    public Map<Byte, Long> getAllByteCounts(Host src, Host dst) {
-        Set<Host> srcSet = new HashSet<Host>(Arrays.asList(src));
-        Set<Host> dstSet = new HashSet<Host>(Arrays.asList(dst));
-        return getAllByteCounts(srcSet, dstSet);
-    }
-
-    public double getDuration(Host src, Host dst) {
-        return getDuration(src, dst, null);
-    }
-
-    public double getDuration(Host src, Host dst, Byte protocol) {
-        Set<Host> srcSet = new HashSet<Host>(Arrays.asList(src));
-        Set<Host> dstSet = new HashSet<Host>(Arrays.asList(dst));
-        return getDuration(srcSet, dstSet, protocol);
-    }
-
-    public double getBitRate(Host src, Host dst) {
-        return getBitRate(src, dst, null);
-    }
-
-    public double getBitRate(Host src, Host dst, Byte protocol) {
-        Set<Host> srcSet = new HashSet<Host>(Arrays.asList(src));
-        Set<Host> dstSet = new HashSet<Host>(Arrays.asList(dst));
-        return getBitRate(srcSet, dstSet, protocol);
-    }
-
-    public Map<Byte, Double> getAllBitRates(Host src, Host dst) {
-        Set<Host> srcSet = new HashSet<Host>(Arrays.asList(src));
-        Set<Host> dstSet = new HashSet<Host>(Arrays.asList(dst));
-        return getAllBitRates(srcSet, dstSet);
-    }
-
-    public long getByteCount(AffinityLink al) {
-        return getByteCount(al, null);
-    }
-
-    public long getByteCount(AffinityLink al, Byte protocol) {
-        Set<Host> srcSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
-        Set<Host> dstSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getFromGroup()));
-        return getByteCount(srcSet, dstSet, protocol);
-    }
-
-    public Map<Byte, Long> getAllByteCounts(AffinityLink al) {
-        Set<Host> srcSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
-        Set<Host> dstSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getFromGroup()));
-        return getAllByteCounts(srcSet, dstSet);
-    }
-
-    public double getDuration(AffinityLink al) {
-        return getDuration(al, null);
-    }
-
-    public double getDuration(AffinityLink al, Byte protocol) {
-        Set<Host> srcSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
-        Set<Host> dstSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getFromGroup()));
-        return getDuration(srcSet, dstSet, protocol);
-    }
-
-    public double getBitRate(AffinityLink al) {
-        return getBitRate(al, null);
-    }
-
-    public double getBitRate(AffinityLink al, Byte protocol) {
-        Set<Host> srcSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
-        Set<Host> dstSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getFromGroup()));
-        return getBitRate(srcSet, dstSet, protocol);
-    }
-
-    public Map<Byte, Double> getAllBitRates(AffinityLink al) {
-        Set<Host> srcSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
-        Set<Host> dstSet = new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getFromGroup()));
-        return getAllBitRates(srcSet, dstSet);
-    }
-
-    public long getByteCount(String srcSubnet, String dstSubnet) {
-        return getByteCount(srcSubnet, dstSubnet, null);
-    }
-
-    public long getByteCount(String srcSubnet, String dstSubnet, Byte protocol) {
-        Set<Host> srcSet = getSrcHosts(srcSubnet, dstSubnet);
-        Set<Host> dstSet = getSrcHosts(dstSubnet, srcSubnet); // reverse arguments
-        return getByteCount(srcSet, dstSet, protocol);
-    }
-
-    public Map<Byte, Long> getAllByteCounts(String srcSubnet, String dstSubnet) {
-        Set<Host> srcSet = getSrcHosts(srcSubnet, dstSubnet);
-        Set<Host> dstSet = getSrcHosts(dstSubnet, srcSubnet); // reverse arguments
-        return getAllByteCounts(srcSet, dstSet);
-    }
-
-    public double getDuration(String srcSubnet, String dstSubnet) {
-        return getDuration(srcSubnet, dstSubnet, null);
-    }
-
-    public double getDuration(String srcSubnet, String dstSubnet, Byte protocol) {
-        Set<Host> srcSet = getSrcHosts(srcSubnet, dstSubnet);
-        Set<Host> dstSet = getSrcHosts(dstSubnet, srcSubnet); // reverse arguments
-        return getDuration(srcSet, dstSet, protocol);
-    }
-
-    public double getBitRate(String srcSubnet, String dstSubnet) {
-        return getBitRate(srcSubnet, dstSubnet, null);
-    }
+    /* Because the generic stats API relies on having two Set<Host>
+     * arguments, the next series of functions converts various
+     * Objects into Set<Host>.  */
 
-    public double getBitRate(String srcSubnet, String dstSubnet, Byte protocol) {
-        Set<Host> srcSet = getSrcHosts(srcSubnet, dstSubnet);
-        Set<Host> dstSet = getSrcHosts(dstSubnet, srcSubnet); // reverse arguments
-        return getBitRate(srcSet, dstSet, protocol);
+    /* Host -> Set<Host> */
+    private Set<Host> getSet(Host h) {
+        return new HashSet<Host>(Arrays.asList(h));
     }
 
-    public Map<Byte, Double> getAllBitRates(String srcSubnet, String dstSubnet) {
-        Set<Host> srcSet = getSrcHosts(srcSubnet, dstSubnet);
-        Set<Host> dstSet = getSrcHosts(dstSubnet, srcSubnet); // reverse arguments
-        return getAllBitRates(srcSet, dstSet);
+    /* AffinityLink -> Set of source Hosts */
+    private Set<Host> getSrcSet(AffinityLink al) {
+        return new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
     }
 
-    public Map<Host, Long> getIncomingHostByteCounts(String subnet) {
-        return getIncomingHostByteCounts(subnet, null);
+    /* AffinityLink -> Set of destination Hosts */
+    private Set<Host> getDstSet(AffinityLink al) {
+        return new HashSet<Host>(this.affinityManager.getAllElementsByHost(al.getToGroup()));
     }
 
-    public Map<Host, Long> getIncomingHostByteCounts(String subnet, Byte protocol) {
-         Set<HostNodeConnector> allHosts = this.hostTracker.getAllHosts();
-         return getIncomingHostByteCounts(subnet, protocol, allHosts);
+    /* srcSubnet, dstSubnet -> Set of Hosts in srcSubnet.  If
+     * srcSubnet is null, will return all hosts *not* in dstSubnet. */
+    private Set<Host> getSrcSet(String srcSubnet, String dstSubnet) {
+        if (srcSubnet == null && dstSubnet == null) {
+            log.debug("Source and destination subnets cannot both be null.");
+            return new HashSet<Host>();
+        }
+        if (srcSubnet == null)
+            return getHostsNotInSubnet(dstSubnet);
+        else
+            return getHostsInSubnet(srcSubnet);
     }
 
+    /* srcSubnet, dstSubnet -> Set of Hosts in dstSubnet.  This has
+     * the same logic as the previous method, so just flip the
+     * arguments. */
+    private Set<Host> getDstSet(String srcSubnet, String dstSubnet) {
+        return getSrcSet(dstSubnet, srcSubnet);
+    }
+
+    /* Basic getters for host pair statistics */
+    public long getByteCount(Host src, Host dst) { return getByteCount(src, dst, null); }
+    public long getByteCount(Host src, Host dst, Byte protocol) { return getByteCount(getSet(src), getSet(dst), protocol); }
+    public Map<Byte, Long> getAllByteCounts(Host src, Host dst) { return getAllByteCounts(getSet(src), getSet(dst)); }
+    public long getPacketCount(Host src, Host dst) { return getPacketCount(src, dst, null); }
+    public long getPacketCount(Host src, Host dst, Byte protocol) { return getPacketCount(getSet(src), getSet(dst), protocol); }
+    public Map<Byte, Long> getAllPacketCounts(Host src, Host dst) { return getAllPacketCounts(getSet(src), getSet(dst)); }
+    public double getDuration(Host src, Host dst) { return getDuration(src, dst, null); }
+    public double getDuration(Host src, Host dst, Byte protocol) { return getDuration(getSet(src), getSet(dst), protocol); }
+    public Map<Byte, Double> getAllDurations(Host src, Host dst) { return getAllDurations(getSet(src), getSet(dst)); }
+    public double getBitRate(Host src, Host dst) { return getBitRate(src, dst, null); }
+    public double getBitRate(Host src, Host dst, Byte protocol) { return getBitRate(getSet(src), getSet(dst), protocol); }
+    public Map<Byte, Double> getAllBitRates(Host src, Host dst) { return getAllBitRates(getSet(src), getSet(dst)); }
+
+    /* Basic getters for affinity link statistics */
+    public long getByteCount(AffinityLink al) { return getByteCount(al, null); }
+    public long getByteCount(AffinityLink al, Byte protocol) { return getByteCount(getSrcSet(al), getDstSet(al), protocol); }
+    public Map<Byte, Long> getAllByteCounts(AffinityLink al) { return getAllByteCounts(getSrcSet(al), getDstSet(al)); }
+    public long getPacketCount(AffinityLink al) { return getPacketCount(al, null); }
+    public long getPacketCount(AffinityLink al, Byte protocol) { return getPacketCount(getSrcSet(al), getDstSet(al), protocol); }
+    public Map<Byte, Long> getAllPacketCounts(AffinityLink al) { return getAllPacketCounts(getSrcSet(al), getDstSet(al)); }
+    public double getDuration(AffinityLink al) { return getDuration(al, null); }
+    public double getDuration(AffinityLink al, Byte protocol) { return getDuration(getSrcSet(al), getDstSet(al), protocol); }
+    public Map<Byte, Double> getAllDurations(AffinityLink al) { return getAllDurations(getSrcSet(al), getDstSet(al)); }
+    public double getBitRate(AffinityLink al) { return getBitRate(al, null); }
+    public double getBitRate(AffinityLink al, Byte protocol) { return getBitRate(getSrcSet(al), getDstSet(al), protocol); }
+    public Map<Byte, Double> getAllBitRates(AffinityLink al) { return getAllBitRates(getSrcSet(al), getDstSet(al)); }
+
+    /* Basic getters for subnet statistics */
+    public long getByteCount(String srcSub, String dstSub) { return getByteCount(srcSub, dstSub, null); }
+    public long getByteCount(String srcSub, String dstSub, Byte protocol) { return getByteCount(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub), protocol); }
+    public Map<Byte, Long> getAllByteCounts(String srcSub, String dstSub) { return getAllByteCounts(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub)); }
+    public long getPacketCount(String srcSub, String dstSub) { return getPacketCount(srcSub, dstSub, null); }
+    public long getPacketCount(String srcSub, String dstSub, Byte protocol) { return getPacketCount(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub), protocol); }
+    public Map<Byte, Long> getAllPacketCounts(String srcSub, String dstSub) { return getAllPacketCounts(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub)); }
+    public double getDuration(String srcSub, String dstSub) { return getDuration(srcSub, dstSub, null); }
+    public double getDuration(String srcSub, String dstSub, Byte protocol) { return getDuration(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub), protocol); }
+    public Map<Byte, Double> getAllDurations(String srcSub, String dstSub) { return getAllDurations(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub)); }
+    public double getBitRate(String srcSub, String dstSub) { return getBitRate(srcSub, dstSub, null); }
+    public double getBitRate(String srcSub, String dstSub, Byte protocol) { return getBitRate(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub), protocol); }
+    public Map<Byte, Double> getAllBitRates(String srcSub, String dstSub) { return getAllBitRates(getSrcSet(srcSub, dstSub), getDstSet(srcSub, dstSub)); }
+    
     /* Returns all hosts that transferred data into this subnet. */
     public Map<Host, Long> getIncomingHostByteCounts(String subnet, Byte protocol, Set<HostNodeConnector> allHosts) {
         Map<Host, Long> hosts = new HashMap<Host, Long>();
@@ -404,10 +385,19 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return hosts;
     }
 
-    private Set<Host> getHostsNotInSubnet(String subnet) {
-        return getHostsNotInSubnet(subnet, this.hostTracker.getAllHosts());
+    public Map<Host, Long> getIncomingHostByteCounts(String subnet) {
+        return getIncomingHostByteCounts(subnet, null);
     }
 
+    public Map<Host, Long> getIncomingHostByteCounts(String subnet, Byte protocol) {
+         Set<HostNodeConnector> allHosts = this.hostTracker.getAllHosts();
+         return getIncomingHostByteCounts(subnet, protocol, allHosts);
+    }
+
+    /* Hosts in allHosts that are not part of the subnet. This is
+     * useful when we need statistics about, e.g., all data into a
+     * particular subnet (so data from hosts outside of that
+     * subnet).*/
     protected Set<Host> getHostsNotInSubnet(String subnet, Set<HostNodeConnector> allHosts) {
         Set<Host> hostsInSubnet = getHostsInSubnet(subnet, allHosts);
         Set<HostNodeConnector> otherHosts = new HashSet<HostNodeConnector>(allHosts); // copy constructor
@@ -418,22 +408,11 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return hostsNotInSubnet;
     }
 
-    // Handles null subnets
-    private Set<Host> getSrcHosts(String srcSubnet, String dstSubnet) {
-        if (srcSubnet == null && dstSubnet == null) {
-            log.debug("Source and destination subnets cannot both be null.");
-            return new HashSet<Host>();
-        }
-        if (srcSubnet == null)
-            return getHostsNotInSubnet(dstSubnet);
-        else
-            return getHostsInSubnet(srcSubnet);
-    }
-
-    private Set<Host> getHostsInSubnet(String subnet) {
-        return getHostsInSubnet(subnet, this.hostTracker.getAllHosts());
+    private Set<Host> getHostsNotInSubnet(String subnet) {
+        return getHostsNotInSubnet(subnet, this.hostTracker.getAllHosts());
     }
 
+    /* Returns the set of hosts that are part of this subnet. */
     protected Set<Host> getHostsInSubnet(String subnet, Set<HostNodeConnector> allHosts) {
         InetAddress ip;
         Short mask;
@@ -449,7 +428,7 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
             return hosts;
         }
 
-        // Match on subnetes
+        // Match on subnets
         InetAddress targetSubnet = getSubnet(ip, mask);
         for (HostNodeConnector host : allHosts) {
             InetAddress hostSubnet = getSubnet(host.getNetworkAddress(), mask);
@@ -459,6 +438,11 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         return hosts;
     }
 
+    private Set<Host> getHostsInSubnet(String subnet) {
+        return getHostsInSubnet(subnet, this.hostTracker.getAllHosts());
+    }
+
+    /* Get the subnet associated with this IP and mask. */
     private InetAddress getSubnet(InetAddress ip, Short mask) {
         byte[] prefix = ip.getAddress();
         InetAddress newIP = null;