import sys
import time
-from stats import Stats
from subnet import SubnetControl
from affinity_control import AffinityControl
elif (rest_type == "PUT"):
headers = {'content-type': 'application/json'}
resp = requests.put(url, auth=('admin', 'admin'), data=json.dumps(payload), headers=headers)
+ return resp.status_code
elif (rest_type == "DELETE"):
resp = requests.delete(url, auth=('admin', 'admin'))
### Host Statistics
-def stats_hosts(src, dst):
+def stats_hosts(src, dst, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s" % (src, dst)
data = rest_method(url, "GET")
- print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ if (do_print):
+ print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ return data
-def stats_hosts_protocol(src, dst, protocol):
+def stats_hosts_protocol(src, dst, protocol, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/%d" % (src, dst, protocol)
data = rest_method(url, "GET")
- print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ if (do_print):
+ print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ return data
-def all_stats_hosts(src, dst):
+def all_stats_hosts(src, dst, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/all" % (src, dst)
- data = rest_method(url, "GET")["stats"]
- for entry in data:
- stat = entry["stat"]
- print("protocol %s: %s bytes (%s packets) over %s seconds (%s bit/s)" % (entry["protocol"], stat["byteCount"], stat["packetCount"], stat["duration"], stat["bitRate"]))
+ data = rest_method(url, "GET")
+ try:
+ data = convert_all_stats_data(data)
+ if (do_print):
+ for protocol in data:
+ stat = data[protocol]
+ print("protocol %s: %s bytes (%s packets) over %s seconds (%s bit/s)" % (protocol, stat["byteCount"], stat["packetCount"], stat["duration"], stat["bitRate"]))
+ except:
+ data = {}
+ finally:
+ return data
### Affinity link statistics
-def stats_link(al):
+def stats_link(al, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/%s" % al
data = rest_method(url, "GET")
- print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ if (do_print):
+ print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ return data
-def stats_link_protocol(al, protocol):
+def stats_link_protocol(al, protocol, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/%s/%s" % (al, protocol)
data = rest_method(url, "GET")
- print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ if (do_print):
+ print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ return data
-def all_stats_link(al):
+def all_stats_link(al, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/%s/all" % al
- data = rest_method(url, "GET")['stats']
- for entry in data:
- stat = entry["stat"]
- print("protocol %s: %s bytes (%s packets) over %s seconds (%s bit/s)" % (entry["protocol"], stat["byteCount"], stat["packetCount"], stat["duration"], stat["bitRate"]))
+ data = rest_method(url, "GET")
+ try:
+ data = convert_all_stats_data(data)
+ if (do_print):
+ for protocol in data:
+ stat = data[protocol]
+ print("protocol %d: %s bytes (%s packets) over %s seconds (%s bit/s)" % (data, stat["byteCount"], stat["packetCount"], stat["duration"], stat["bitRate"]))
+ except:
+ data = {}
+ finally:
+ return data
### Subnet statistics
-def stats_subnet(src_sub, dst_sub):
+def stats_subnet(src_sub, dst_sub, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/%s/%s" % (src_sub, dst_sub)
data = rest_method(url, "GET")
- print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ if (do_print):
+ print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ return data
-def stats_subnet_protocol(src_sub, dst_sub, protocol):
+def stats_subnet_protocol(src_sub, dst_sub, protocol, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/%s/%s/%s" % (src_sub, dst_sub, protocol)
data = rest_method(url, "GET")
- print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ if (do_print):
+ print("%s bytes (%s packets) over %s seconds (%s bit/s)" % (data["byteCount"], data["packetCount"], data["duration"], data["bitRate"]))
+ return do_print
-def all_stats_subnet(src_sub, dst_sub):
+def all_stats_subnet(src_sub, dst_sub, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/%s/%s/all" % (src_sub, dst_sub)
- data = rest_method(url, "GET")['stats']
- for entry in data:
- stat = entry["stat"]
- print("protocol %s: %s bytes (%s packets) over %s seconds (%s bit/s)" % (entry["protocol"], stat["byteCount"], stat["packetCount"], stat["duration"], stat["bitRate"]))
-
-def incoming_hosts(subnet):
- url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/incoming/%s" % subnet
data = rest_method(url, "GET")
+ try:
+ data = convert_all_stats_data(data)
+ if (do_print):
+ for protocol in data:
+ stat = data[protocol]
+ print("protocol %d: %s bytes (%s packets) over %s seconds (%s bit/s)" % (protocol, stat["byteCount"], stat["packetCount"], stat["duration"], stat["bitRate"]))
+ except:
+ data = {}
+ finally:
+ return data
+
+def incoming_hosts(subnet, do_print=True):
+ url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/incoming/%s" % subnet
data = rest_method(url, "GET")['stats']
if (type(data) == type({})):
data = [data]
- for entry in data:
- print("%s bytes from host %s" % (entry['byteCount'], entry['hostIP']))
+ if (do_print):
+ for entry in data:
+ print("%s bytes from host %s" % (entry['byteCount'], entry['hostIP']))
+ return data
-def incoming_hosts_protocol(subnet, protocol):
+def incoming_hosts_protocol(subnet, protocol, do_print=True):
url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/incoming/%s/%s" % (subnet, protocol)
data = rest_method(url, "GET")['data']['entry']
if (type(data) == type({})):
data = [data]
- for entry in data:
- print("%s bytes from host %s" % (entry['byteCount'], entry['hostIP']))
+ if (do_print):
+ for entry in data:
+ print("%s bytes from host %s" % (entry['byteCount'], entry['hostIP']))
+ return data
+
+def convert_all_stats_data(data):
+ try:
+ new_data = {}
+ data = data["stats"]
+ if (type(data) == type({})):
+ data = [data]
+ for entry in data:
+ stat = entry["stat"]
+ protocol = int(entry["protocol"])
+ new_data[protocol] = stat
+ return new_data
+ except Exception as e:
+ pass
+ return {}
# This is not part of the analytics NB API, but it is a necessary step
# if you want to monitor protocols
protocols = [1, 6, 17] # ICMP, TCP, UDP
flows = get_flows()
i = 0
+ success = True
for flow in flows:
i += 1
name = "flow" + str(i)
flow.set_priority(2)
flow.set_protocol(1)
- add_flow(flow, name)
+ flow_success = add_flow(flow, name)
+ if (flow_success != 201):
+ success = False
+ return success
#### Flow control methods
def add_flow(flow, flow_name):
url = "http://localhost:8080/controller/nb/v2/flowprogrammer/default/node/OF/%s/staticFlow/%s" % (flow.node_id, flow_name)
- rest_method(url, "PUT", flow.get_json(flow_name))
+ return rest_method(url, "PUT", flow.get_json(flow_name))
#### End flow control methods
from subnet import SubnetControl
from stats import Stats
+import analytics
+
'''
The instructions for running this demo are located at:
https://wiki.opendaylight.org/view/Project_Proposals:Affinity_Metadata_Service#Current_Status
def set_large_flow_threshold(self, s):
self.stat.set_large_flow_threshold(s)
print "Set threshold for large flows to %d bytes" % s
+ print("-------------------------")
def run(self):
global sigint
while not sigint:
_, is_big = self.stat.refresh()
if is_big and not did_waypoint:
- print "Large flow detected (%d bytes)" % self.stat.get_bytes()
+ print "Large flow detected (%d bytes, %d packets, %3.3f bit/s)" % (self.stat.get_bytes(), self.stat.get_packets(), self.stat.get_bit_rate())
+ print " ICMP: %d bytes, %d packets" % (self.stat.get_bytes(1), self.stat.get_packets(1))
+ print " UDP: %d bytes, %d packets" % (self.stat.get_bytes(17), self.stat.get_packets(17))
+ print " TCP: %d bytes, %d packets" % (self.stat.get_bytes(6), self.stat.get_packets(6))
+ print " other: %d bytes, %d packets" % (self.stat.get_bytes(-1), self.stat.get_packets(-1))
+ print("-------------------------")
ac = AffinityControl()
# First AG: Sources sending data into this subnet
src_ag_name = "sources"
subnet_control = SubnetControl()
subnet_control.add_subnet("defaultSubnet", "10.0.0.254/8")
+ raw_input("[Press enter when mininet is ready] ")
+ print("-------------------------")
+
+ # Add per-protocol flows so we can monitor stats that way
+ x = analytics.add_protocol_flows()
+ if (not x):
+ print "Unable to add per-protocol flows"
+
m = WaypointMonitor(Stats.TYPE_SUBNET, subnet="10.0.0.0/31")
m.set_waypoint("10.0.0.2")
m.set_large_flow_threshold(2000) # 2000 bytes
#!/usr/bin/python
-import httplib2
-import json
+import analytics
'''
Class for keeping track of host statistics
if stat_type == Stats.TYPE_HOST:
self.src = kwargs['src']
self.dst = kwargs['dst']
- self.url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/"
elif stat_type == Stats.TYPE_AL:
self.al = kwargs['al']
- self.url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/"
elif stat_type == Stats.TYPE_SUBNET:
self.subnet = kwargs['subnet']
- self.url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/"
else:
print "incorrect stat type", stat_type
self.stats = {}
+ self.protocol_stats = {}
self.rate_ewma = None
self.large_flow_threshold = 5 * 10**6 # in bytes
- self.http = httplib2.Http(".cache")
- self.http.add_credentials('admin', 'admin')
def __str__(self):
if (self.stat_type == Stats.TYPE_HOST):
# Refresh statistics
def refresh(self):
if (self.stat_type == Stats.TYPE_HOST):
- resp, content = self.http.request(self.url_prefix + self.src + "/" + self.dst, "GET")
+ self.stats = analytics.stats_hosts(self.src, self.dst, False)
+ self.protocol_stats = analytics.all_stats_hosts(self.src, self.dst, False)
elif (self.stat_type == Stats.TYPE_AL):
- resp, content = self.http.request(self.url_prefix + self.al, "GET")
+ self.stats = analytics.stats_link(self.al, False)
+ self.protocol_stats = analytics.all_stats_link(self.al, False)
elif (self.stat_type == Stats.TYPE_SUBNET):
- resp, content = self.http.request(self.url_prefix + "null/null/" + self.subnet, "GET")
+ self.stats = analytics.stats_subnet("null/null", self.subnet, False)
+ self.protocol_stats = analytics.all_stats_subnet("null/null", self.subnet, False)
try:
- self.stats = json.loads(content)
is_fast = self.handle_rate_ewma()
is_big = self.check_large_flow()
return [is_fast, is_big]
- except Exception as e:
- print "error: ", e
+ except:
return [False, False]
def set_large_flow_threshold(self, s):
# Return all hosts that transferred a particular percentage of data into this entity. Right now only supports subnets.
def get_large_incoming_hosts(self):
if (self.stat_type == Stats.TYPE_SUBNET):
- resp, content = self.http.request(self.url_prefix + "incoming/" + self.subnet, "GET")
- data = json.loads(content)
+ data = analytics.incoming_hosts(self.subnet, False)
if (data == {}): return []
- data = data['stats']
ips = []
total_bytes_in = self.get_bytes()
n = len(data)
if (bytes_from_ip >= total_bytes_in / float(n)):
ips.append(ip)
return ips
-
else:
print "Stat type not supported for incoming hosts"
return []
return False
# Bytes
- def get_bytes(self):
+ def get_bytes(self, protocol=None):
try:
- bytes = long(self.stats["byteCount"])
+ if (protocol == None):
+ bytes = long(self.stats["byteCount"])
+ else:
+ bytes = long(self.protocol_stats[protocol]["byteCount"])
except Exception as e:
- print "exception: ", e
bytes = 0
return bytes
+ # Packets
+ def get_packets(self, protocol=None):
+ try:
+ if (protocol == None):
+ packets = long(self.stats["packetCount"])
+ else:
+ packets = long(self.protocol_stats[protocol]["byteCount"])
+ except Exception as e:
+ packets = 0
+ return packets
+
# Bit Rate
def get_bit_rate(self):
try: