double getBitRate(Host src, Host dst, Byte protocol);
Map<Byte, Long> getAllByteCounts(Host src, Host dst);
Map<Byte, Double> getAllBitRates(Host src, Host dst);
- Set<Byte> getProtocols(Host src, Host dst);
// AffinityLink statistics
long getByteCount(AffinityLink al);
double getBitRate(AffinityLink al, Byte protocol);
Map<Byte, Long> getAllByteCounts(AffinityLink al);
Map<Byte, Double> getAllBitRates(AffinityLink al);
- Set<Byte> getProtocols(AffinityLink al);
// Subnet statistics
long getByteCount(String srcSubnet, String dstSubnet);
double getBitRate(String srcSubnet, String dstSubnet, Byte protocol);
Map<Byte, Long> getAllByteCounts(String srcSubnet, String dstSubnet);
Map<Byte, Double> getAllBitRates(String srcSubnet, String dstSubnet);
- Set<Byte> getProtocols(String srcSubnet, String dstSubnet);
// Miscellaneous
Map<Host, Long> getIncomingHostByteCounts(String subnet);
return this.hostsToStats.get(src).get(dst).getAllBitRates();
}
- public Set<Byte> getProtocols(Host src, Host dst) {
- if (this.hostsToStats.get(src) == null ||
- this.hostsToStats.get(src).get(dst) == null)
- return new HashSet<Byte>();
- return this.hostsToStats.get(src).get(dst).getProtocols();
- }
-
public long getByteCount(AffinityLink al) {
return getByteCountOnAffinityLinkInternal(al, null);
}
return getByteCountOnAffinityLinkInternal(al, protocol);
}
- public Set<Byte> getProtocols(AffinityLink al) {
- Set<Byte> protocols = new HashSet<Byte>();
- for (Entry<Host, Host> flow : this.affinityManager.getAllFlowsByHost(al)) {
- Host h1 = flow.getKey();
- Host h2 = flow.getValue();
- Set<Byte> thisProtocols = getProtocols(h1, h2);
- protocols.addAll(thisProtocols);
- }
- return protocols;
- }
-
public Map<Byte, Long> getAllByteCounts(AffinityLink al) {
Map<Byte, Long> byteCounts = new HashMap<Byte, Long>();
Set<Byte> protocols = getProtocols(al);
return bitRates;
}
- public Set<Byte> getProtocols(String srcSubnet, String dstSubnet) {
- if (srcSubnet == null && dstSubnet == null) {
- log.debug("Source and destination subnets cannot both be null.");
- return null;
- }
- Set<Byte> protocols = new HashSet<Byte>();
- Set<Host> srcHosts;
- Set<Host> dstHosts;
- if (srcSubnet == null) {
- dstHosts = getHostsInSubnet(dstSubnet);
- srcHosts = getHostsNotInSubnet(dstSubnet);
- } else if (dstSubnet == null) {
- srcHosts = getHostsInSubnet(srcSubnet);
- dstHosts = getHostsNotInSubnet(srcSubnet);
- } else {
- srcHosts = getHostsInSubnet(srcSubnet);
- dstHosts = getHostsInSubnet(dstSubnet);
- }
-
- for (Host srcHost : srcHosts)
- for (Host dstHost : dstHosts)
- protocols.addAll(getProtocols(srcHost, dstHost));
- return protocols;
- }
-
public Map<Host, Long> getIncomingHostByteCounts(String subnet) {
return getIncomingHostByteCountsInternal(subnet, null);
}
return hosts;
}
+ private Set<Byte> getProtocols(Host src, Host dst) {
+ if (this.hostsToStats.get(src) == null ||
+ this.hostsToStats.get(src).get(dst) == null)
+ return new HashSet<Byte>();
+ return this.hostsToStats.get(src).get(dst).getProtocols();
+ }
+
+ private Set<Byte> getProtocols(AffinityLink al) {
+ Set<Byte> protocols = new HashSet<Byte>();
+ for (Entry<Host, Host> flow : this.affinityManager.getAllFlowsByHost(al)) {
+ Host h1 = flow.getKey();
+ Host h2 = flow.getValue();
+ Set<Byte> thisProtocols = getProtocols(h1, h2);
+ protocols.addAll(thisProtocols);
+ }
+ return protocols;
+ }
+
+ private Set<Byte> getProtocols(String srcSubnet, String dstSubnet) {
+ if (srcSubnet == null && dstSubnet == null) {
+ log.debug("Source and destination subnets cannot both be null.");
+ return null;
+ }
+ Set<Byte> protocols = new HashSet<Byte>();
+ Set<Host> srcHosts;
+ Set<Host> dstHosts;
+ if (srcSubnet == null) {
+ dstHosts = getHostsInSubnet(dstSubnet);
+ srcHosts = getHostsNotInSubnet(dstSubnet);
+ } else if (dstSubnet == null) {
+ srcHosts = getHostsInSubnet(srcSubnet);
+ dstHosts = getHostsNotInSubnet(srcSubnet);
+ } else {
+ srcHosts = getHostsInSubnet(srcSubnet);
+ dstHosts = getHostsInSubnet(dstSubnet);
+ }
+
+ for (Host srcHost : srcHosts)
+ for (Host dstHost : dstHosts)
+ protocols.addAll(getProtocols(srcHost, dstHost));
+ return protocols;
+ }
+
private Set<Host> getHostsNotInSubnet(String subnet) {
Set<Host> hostsInSubnet = getHostsInSubnet(subnet);
Set<HostNodeConnector> otherHosts = this.hostTracker.getAllHosts();
--- /dev/null
+/*
+ * Copyright (c) 2013 Plexxi, 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.affinity.analytics.northbound;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class AllHostStatistics {
+ @XmlElement
+ private Map<Byte, HostStatistics> data;
+
+ public AllHostStatistics() {
+ super();
+ this.data = new HashMap<Byte, HostStatistics>();
+ }
+
+ public void addHostStat(Byte proto, HostStatistics stat) {
+ this.data.put(proto, stat);
+ }
+}
return new HostStatistics(srcHost, dstHost, byteCount, bitRate);
}
+ /**
+ * Returns Host Statistics for a (src, dst) pair and a particular protocol
+ *
+ * @param containerName: Name of the Container
+ * @param srcIP: Source IP
+ * @param dstIP: Destination IP
+ * @param protocol: Protocol of interest
+ * @return Host Statistics for a given Node.
+ */
+ @Path("/{containerName}/hoststats/{srcIP}/{dstIP}/{protocol}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @TypeHint(HostStatistics.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 404, condition = "The containerName is not found"),
+ @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
+ public HostStatistics getHostStatistics(
+ @PathParam("containerName") String containerName,
+ @PathParam("srcIP") String srcIP,
+ @PathParam("dstIP") String dstIP,
+ @PathParam("protocol") String protocol) {
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
+ throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
+ handleDefaultDisabled(containerName);
+
+ IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
+ if (analyticsManager == null)
+ throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
+
+ Host srcHost = handleHostAvailability(containerName, srcIP);
+ Host dstHost = handleHostAvailability(containerName, dstIP);
+ long byteCount = analyticsManager.getByteCount(srcHost, dstHost, IPProtocols.getProtocolNumberByte(protocol));
+ double bitRate = analyticsManager.getBitRate(srcHost, dstHost, IPProtocols.getProtocolNumberByte(protocol));
+
+ return new HostStatistics(srcHost, dstHost, byteCount, bitRate);
+ }
+
+ /**
+ * Returns all Host Statistics for a (src, dst) pair
+ *
+ * @param containerName: Name of the Container
+ * @param srcIP: Source IP
+ * @param dstIP: Destination IP
+ * @return Host Statistics for a given Node.
+ */
+ @Path("/{containerName}/hoststats/{srcIP}/{dstIP}/all")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @TypeHint(AllHostStatistics.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 404, condition = "The containerName is not found"),
+ @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
+ public AllHostStatistics getAllHostStatistics(
+ @PathParam("containerName") String containerName,
+ @PathParam("srcIP") String srcIP,
+ @PathParam("dstIP") String dstIP) {
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
+ throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
+ handleDefaultDisabled(containerName);
+
+ IAnalyticsManager analyticsManager = getAnalyticsService(containerName);
+ if (analyticsManager == null)
+ throw new ServiceUnavailableException("Analytics " + RestMessages.SERVICEUNAVAILABLE.toString());
+
+ Host srcHost = handleHostAvailability(containerName, srcIP);
+ Host dstHost = handleHostAvailability(containerName, dstIP);
+ Map<Byte, Long> byteCounts = analyticsManager.getAllByteCounts(srcHost, dstHost);
+ Map<Byte, Double> bitRates = analyticsManager.getAllBitRates(srcHost, dstHost);
+ AllHostStatistics allStats = new AllHostStatistics();
+ for (Byte protocol : byteCounts.keySet())
+ allStats.addHostStat(protocol, new HostStatistics(srcHost, dstHost, byteCounts.get(protocol), bitRates.get(protocol)));
+ System.out.println(">>> " + allStats);
+ return allStats;
+ }
+
/**
* Returns the affinity link statistics for a given link.
*
@PathParam("containerName") String containerName,
@PathParam("ip") String ip,
@PathParam("mask") String mask) {
+ // TODO: Change AllHosts class name to something better
if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this))
throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
handleDefaultDisabled(containerName);
from subnet import SubnetControl
from affinity_control import AffinityControl
-# 1. Start the controller
-# 2. On the local machine (e.g., your laptop), start this script.
-# > python analytics.py
-# 3. On the mininet VM, run:
-# > sudo mn --controller=remote,ip=192.168.56.1 --topo tree,2
-# > h1 ping h3
-# 4. Give commands to analytics.py. For instance:
-# > host bytes 10.0.0.1 10.0.0.3
-# (There is a usage prompt that prints at the beginning of analytics.py)
-# 5. Type 'quit' to exit analytics.py
+# Generic REST query
+def rest_method(url, rest_type):
+ h = httplib2.Http(".cache")
+ h.add_credentials('admin', 'admin')
+ resp, content = h.request(url, rest_type)
+ return json.loads(content)
+
+### Host Statistics
+
+def bytes_between_hosts(src, dst):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s" % (src, dst)
+ data = rest_method(url, "GET")
+ print("%d bytes between %s and %s" % (int(data["byteCount"]), src, dst))
+
+def bytes_between_hosts_protocol(src, dst, protocol):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/%d" % (src, dst, protocol)
+ data = rest_method(url, "GET")
+ print("%d bytes between %s and %s for protocol %d" % (int(data["byteCount"]), src, dst, protocol))
+
+def rate_between_hosts(src, dst):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s" % (src, dst)
+ data = rest_method(url, "GET")
+ print("%s bit/s between %s and %s" % (data["bitRate"], src, dst))
+
+def rate_between_hosts_protocol(src, dst, protocol):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/%d" % (src, dst, protocol)
+ data = rest_method(url, "GET")
+ print("%s bit/s between %s and %s on protocol %d" % (data["bitRate"], src, dst, protocol))
+
+def all_byte_counts_hosts(src, dst):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/all" % (src, dst)
+ data = rest_method(url, "GET")['data']['entry']
+ for entry in data:
+ protocol = entry['key']
+ byte_count = entry['value']['byteCount']
+ print("%s bytes from protocol %s" % (byte_count, protocol))
+
+def all_bit_rates_hosts(src, dst):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/all" % (src, dst)
+ data = rest_method(url, "GET")['data']['entry']
+ for entry in data:
+ protocol = entry['key']
+ bit_rate = entry['value']['bitRate']
+ print("%s bit/s from protocol %s" % (bit_rate, protocol))
+
+### Affinity link statistics
def run_interactive_mode():
- print "Usage: [host | link] [bytes | rate] [src dst | link-name]"
+ print "Usage: [host | link] [src dst | link-name] {protocol}"
# Demo mode
while True:
request = request.split()
request_type = request[0]
- if (request_type == "quit"):
+ if (request_type == "quit" or request_type == "exit"):
sys.exit()
if (request_type == "host"):
- action = request[1]
- src, dst = request[2:4]
- host_stat = Stats(Stats.TYPE_HOST, src=src, dst=dst)
- if (action == "bytes"):
- print("%d bytes between %s and %s" % (host_stat.get_bytes(), src, dst))
- elif (action == "rate"):
- print("%f bit/s between %s and %s" % (host_stat.get_bit_rate(), src, dst))
- else:
- raise Exception
+ if (len(request) == 3):
+ src, dst = request[1:3]
+ bytes_between_hosts(src, dst)
+ rate_between_hosts(src, dst)
+ all_byte_counts_hosts(src, dst)
+ all_bit_rates_hosts(src, dst)
+ elif (len(request) == 4):
+ src, dst, protocol = request[1:4]
+ bytes_between_hosts_protocol(src, dst, int(protocol))
+ rate_between_hosts_protocol(src, dst, int(protocol))
elif (request_type == "link"):
- action = request[1]
- link = request[2]
- link_stat = Stats(Stats.TYPE_AL, al=link)
- if (action == "bytes"):
- print("%d bytes on %s" % (link_stat.get_bytes(), link))
- elif (action == "rate"):
- print("%f bit/s on %s" % (link_stat.get_bit_rate(), link))
- else:
- raise Exception
-
- elif (request_type == "prefix"):
- prefix = request[1]
- h = httplib2.Http(".cache")
- h.add_credentials("admin", "admin")
- url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/prefixstats/"
- resp, content = h.request(url_prefix + prefix, "GET")
- if (resp.status == 200):
- data = json.loads(content)
- print data['byteCount'], "bytes"
- else:
- raise Exception
- except Exception as e:
- print "Error"
- print e
+ link = request[1]
+
+ elif (request_type == "subnet"):
+ subnet = request[1]
def main():
subnet_control.add_subnet("defaultSubnet", "10.0.0.254/8")
# Set up an affinity link
- affinity_control = AffinityControl()
- affinity_control.add_affinity_group("testAG1", ips=["10.0.0.1", "10.0.0.2"])
- affinity_control.add_affinity_group("testAG2", ips=["10.0.0.3", "10.0.0.4"])
- affinity_control.add_affinity_link("testAL", "testAG1", "testAG2")
- raw_input("[Press enter to continue]" )
+# affinity_control = AffinityControl()
+# affinity_control.add_affinity_group("testAG1", ips=["10.0.0.1", "10.0.0.2"])
+# affinity_control.add_affinity_group("testAG2", ips=["10.0.0.3", "10.0.0.4"])
+# affinity_control.add_affinity_link("testAL", "testAG1", "testAG2")
+# raw_input("[Press enter to continue]" )
run_interactive_mode()