8 import random # noqa # FIXME: This script seems to be unfinished!
18 "deviceId": "of:0000000000000001",
43 def __init__(self, verbose=False):
44 self.verbose = verbose
47 self.start = time.time()
50 def __exit__(self, *args):
51 self.end = time.time()
52 self.secs = self.end - self.start
53 self.msecs = self.secs * 1000 # millisecs
55 print("elapsed time: %f ms" % self.msecs)
58 class Counter(object):
59 def __init__(self, start=0):
60 self.lock = threading.Lock()
63 def increment(self, value=1):
73 def _prepare_post(cntl, method, flows, template=None):
74 """Creates a POST http requests to configure a flow in configuration datastore.
77 :param cntl: controller's ip address or hostname
79 :param method: determines http request method
81 :param flows: list of flow details
83 :param template: flow template to be to be filled
86 :returns req: http request object
90 url = 'http://' + cntl + ':' + '8181/onos/v1/flows/' + dev_id
91 flow = copy.deepcopy(template)
92 flow["deviceId"] = dev_id
93 flow["selector"]["criteria"][1]["ip"] = '%s/32' % str(netaddr.IPAddress(ip))
94 req_data = json.dumps(flow)
95 req = requests.Request(method, url, headers={'Content-Type': 'application/json'},
96 data=req_data, auth=('onos', 'rocks'))
100 def _prepare_delete(cntl, method, flows, template=None):
101 """Creates a DELETE http requests to configure a flow in configuration datastore.
104 :param cntl: controller's ip address or hostname
106 :param method: determines http request method
108 :param flows: list of flow details
110 :param template: flow template to be to be filled
113 :returns req: http request object
116 dev_id, flow_id = fl1
117 url = 'http://' + cntl + ':' + '8181/onos/v1/flows/' + dev_id + '/' + flow_id
118 req = requests.Request(method, url, auth=('onos', 'rocks'))
122 def _wt_request_sender(thread_id, preparefnc, inqueue=None, exitevent=None, controllers=[], restport='',
123 template=None, outqueue=None, method=None):
124 """The funcion sends http requests.
126 Runs in the working thread. It reads out flow details from the queue and sends apropriate http requests
130 :param thread_id: thread id
132 :param preparefnc: function to preparesthe http request
134 :param inqueue: input queue, flow details are comming from here
136 :param exitevent: event to notify working thread that parent (task executor) stopped filling the input queue
138 :param controllers: a list of controllers' ip addresses or hostnames
140 :param restport: restconf port
142 :param template: flow template used for creating flow content
144 :param outqueue: queue where the results should be put
146 :param method: method derermines the type of http request
149 nothing, results must be put into the output queue
151 ses = requests.Session()
152 cntl = controllers[0]
153 counter = [0 for i in range(600)]
158 flowlist = inqueue.get(timeout=1)
160 if exitevent.is_set() and inqueue.empty():
163 req = preparefnc(cntl, method, flowlist, template=template)
164 # prep = ses.prepare_request(req)
167 rsp = ses.send(prep, timeout=5)
168 except requests.exceptions.Timeout:
171 counter[rsp.status_code] += 1
173 for i, v in enumerate(counter):
179 def get_device_ids(controller='127.0.0.1', port=8181):
180 """Returns a list of switch ids"""
181 rsp = requests.get(url='http://{0}:{1}/onos/v1/devices'.format(controller, port), auth=('onos', 'rocks'))
182 if rsp.status_code != 200:
184 devices = json.loads(rsp.content)['devices']
185 ids = [d['id'] for d in devices if 'of:' in d['id']]
189 def get_flow_ids(controller='127.0.0.1', port=8181):
190 """Returns a list of flow ids"""
191 rsp = requests.get(url='http://{0}:{1}/onos/v1/flows'.format(controller, port), auth=('onos', 'rocks'))
192 if rsp.status_code != 200:
194 flows = json.loads(rsp.content)['flows']
195 ids = [f['id'] for f in flows]
199 def get_flow_simple_stats(controller='127.0.0.1', port=8181):
200 """Returns a list of flow ids"""
201 rsp = requests.get(url='http://{0}:{1}/onos/v1/flows'.format(controller, port), auth=('onos', 'rocks'))
202 if rsp.status_code != 200:
204 flows = json.loads(rsp.content)['flows']
207 if f['state'] not in res:
214 def get_flow_device_pairs(controller='127.0.0.1', port=8181, flow_details=[]):
215 """Pairing flows from controller with deteils we used ofr creation"""
216 rsp = requests.get(url='http://{0}:{1}/onos/v1/flows'.format(controller, port), auth=('onos', 'rocks'))
217 if rsp.status_code != 200:
219 flows = json.loads(rsp.content)['flows']
220 # print "Flows", flows
221 # print "Details", flow_details
222 for dev_id, ip in flow_details:
223 # print "looking for details", dev_id, ip
225 # lets identify if it is our flow
226 if f["treatment"]["instructions"][0]["type"] != "DROP":
229 if f["deviceId"] == dev_id:
230 if "ip" in f["selector"]["criteria"][0]:
232 elif "ip" in f["selector"]["criteria"][1]:
236 # print "Comparing", '%s/32' % str(netaddr.IPAddress(ip))
237 if f["selector"]["criteria"][item_idx]["ip"] == '%s/32' % str(netaddr.IPAddress(ip)):
238 # print dev_id, ip, f
239 yield dev_id, f["id"]
243 def get_flow_to_remove(controller='127.0.0.1', port=8181):
244 """Pairing flows from controller with deteils we used ofr creation"""
245 rsp = requests.get(url='http://{0}:{1}/onos/v1/flows'.format(controller, port), auth=('onos', 'rocks'))
246 if rsp.status_code != 200:
248 flows = json.loads(rsp.content)['flows']
249 # print "Flows", flows
250 # print "Details", flow_details
253 # lets identify if it is our flow
254 if f["treatment"]["instructions"][0]["type"] != "NOACTION":
257 if "ip" in f["selector"]["criteria"][0]:
259 elif "ip" in f["selector"]["criteria"][1]:
263 # print "Comparing", '%s/32' % str(netaddr.IPAddress(ip))
264 ipstr = f["selector"]["criteria"][item_idx]["ip"]
265 if '10.' in ipstr and '/32' in ipstr:
266 # print dev_id, ip, f
267 yield (f["deviceId"], f["id"])
272 parser = argparse.ArgumentParser(description='Flow programming performance test: First adds and then deletes flows '
273 'into the config tree, as specified by optional parameters.')
275 parser.add_argument('--host', default='127.0.0.1',
276 help='Host where onos controller is running (default is 127.0.0.1)')
277 parser.add_argument('--port', default='8181',
278 help='Port on which onos\'s RESTCONF is listening (default is 8181)')
280 in_args = parser.parse_args(*argv)
284 base_dev_ids = get_device_ids(controller=in_args.host)
285 base_flow_ids = get_flow_ids(controller=in_args.host)
287 ip_addr = Counter(int(netaddr.IPAddress('10.0.0.1'))) # noqa # FIXME: This script seems to be unfinished!
289 preparefnc = _prepare_post # noqa # FIXME: This script seems to be unfinished!
292 print " devices:", len(base_dev_ids)
293 print " flows :", len(base_flow_ids)
295 # lets print some stats
296 print "\n\nSome stats monitoring ...."
297 print get_flow_simple_stats(controller=in_args.host)
300 if __name__ == "__main__":