8 import random # noqa # FIXME: This script seems to be unfinished!
18 "deviceId": "of:0000000000000001",
19 "treatment": {"instructions": [{"type": "NOACTION"}], "deferred": []},
22 {"type": "ETH_TYPE", "ethType": 2048},
23 {"type": "IPV4_DST", "ip": "10.0.0.0/32"},
30 def __init__(self, verbose=False):
31 self.verbose = verbose
34 self.start = time.time()
37 def __exit__(self, *args):
38 self.end = time.time()
39 self.secs = self.end - self.start
40 self.msecs = self.secs * 1000 # millisecs
42 print("elapsed time: %f ms" % self.msecs)
45 class Counter(object):
46 def __init__(self, start=0):
47 self.lock = threading.Lock()
50 def increment(self, value=1):
60 def _prepare_post(cntl, method, flows, template=None):
61 """Creates a POST http requests to configure a flow in configuration datastore.
64 :param cntl: controller's ip address or hostname
66 :param method: determines http request method
68 :param flows: list of flow details
70 :param template: flow template to be to be filled
73 :returns req: http request object
77 url = "http://" + cntl + ":" + "8181/onos/v1/flows/" + dev_id
78 flow = copy.deepcopy(template)
79 flow["deviceId"] = dev_id
80 flow["selector"]["criteria"][1]["ip"] = "%s/32" % str(netaddr.IPAddress(ip))
81 req_data = json.dumps(flow)
82 req = requests.Request(
85 headers={"Content-Type": "application/json"},
87 auth=("onos", "rocks"),
92 def _prepare_delete(cntl, method, flows, template=None):
93 """Creates a DELETE http requests to configure a flow in configuration datastore.
96 :param cntl: controller's ip address or hostname
98 :param method: determines http request method
100 :param flows: list of flow details
102 :param template: flow template to be to be filled
105 :returns req: http request object
108 dev_id, flow_id = fl1
109 url = "http://" + cntl + ":" + "8181/onos/v1/flows/" + dev_id + "/" + flow_id
110 req = requests.Request(method, url, auth=("onos", "rocks"))
114 def _wt_request_sender(
125 """The funcion sends http requests.
127 Runs in the working thread. It reads out flow details from the queue and sends apropriate http requests
131 :param thread_id: thread id
133 :param preparefnc: function to preparesthe http request
135 :param inqueue: input queue, flow details are comming from here
137 :param exitevent: event to notify working thread that parent (task executor) stopped filling the input queue
139 :param controllers: a list of controllers' ip addresses or hostnames
141 :param restport: restconf port
143 :param template: flow template used for creating flow content
145 :param outqueue: queue where the results should be put
147 :param method: method derermines the type of http request
150 nothing, results must be put into the output queue
152 ses = requests.Session()
153 cntl = controllers[0]
154 counter = [0 for i in range(600)]
159 flowlist = inqueue.get(timeout=1)
161 if exitevent.is_set() and inqueue.empty():
164 req = preparefnc(cntl, method, flowlist, template=template)
165 # prep = ses.prepare_request(req)
168 rsp = ses.send(prep, timeout=5)
169 except requests.exceptions.Timeout:
172 counter[rsp.status_code] += 1
174 for i, v in enumerate(counter):
180 def get_device_ids(controller="127.0.0.1", port=8181):
181 """Returns a list of switch ids"""
183 url="http://{0}:{1}/onos/v1/devices".format(controller, port),
184 auth=("onos", "rocks"),
186 if rsp.status_code != 200:
188 devices = json.loads(rsp.content)["devices"]
189 ids = [d["id"] for d in devices if "of:" in d["id"]]
193 def get_flow_ids(controller="127.0.0.1", port=8181):
194 """Returns a list of flow ids"""
196 url="http://{0}:{1}/onos/v1/flows".format(controller, port),
197 auth=("onos", "rocks"),
199 if rsp.status_code != 200:
201 flows = json.loads(rsp.content)["flows"]
202 ids = [f["id"] for f in flows]
206 def get_flow_simple_stats(controller="127.0.0.1", port=8181):
207 """Returns a list of flow ids"""
209 url="http://{0}:{1}/onos/v1/flows".format(controller, port),
210 auth=("onos", "rocks"),
212 if rsp.status_code != 200:
214 flows = json.loads(rsp.content)["flows"]
217 if f["state"] not in res:
224 def get_flow_device_pairs(controller="127.0.0.1", port=8181, flow_details=[]):
225 """Pairing flows from controller with deteils we used ofr creation"""
227 url="http://{0}:{1}/onos/v1/flows".format(controller, port),
228 auth=("onos", "rocks"),
230 if rsp.status_code != 200:
232 flows = json.loads(rsp.content)["flows"]
233 for dev_id, ip in flow_details:
235 # lets identify if it is our flow
236 if f["treatment"]["instructions"][0]["type"] != "DROP":
238 if f["deviceId"] == dev_id:
239 if "ip" in f["selector"]["criteria"][0]:
241 elif "ip" in f["selector"]["criteria"][1]:
245 if f["selector"]["criteria"][item_idx]["ip"] == "%s/32" % str(
246 netaddr.IPAddress(ip)
248 yield dev_id, f["id"]
252 def get_flow_to_remove(controller="127.0.0.1", port=8181):
253 """Pairing flows from controller with deteils we used ofr creation"""
255 url="http://{0}:{1}/onos/v1/flows".format(controller, port),
256 auth=("onos", "rocks"),
258 if rsp.status_code != 200:
260 flows = json.loads(rsp.content)["flows"]
263 # lets identify if it is our flow
264 if f["treatment"]["instructions"][0]["type"] != "NOACTION":
266 if "ip" in f["selector"]["criteria"][0]:
268 elif "ip" in f["selector"]["criteria"][1]:
272 ipstr = f["selector"]["criteria"][item_idx]["ip"]
273 if "10." in ipstr and "/32" in ipstr:
274 yield (f["deviceId"], f["id"])
279 parser = argparse.ArgumentParser(
280 description="Flow programming performance test: First adds and then deletes flows "
281 "into the config tree, as specified by optional parameters."
287 help="Host where onos controller is running (default is 127.0.0.1)",
292 help="Port on which onos's RESTCONF is listening (default is 8181)",
295 in_args = parser.parse_args(*argv)
299 base_dev_ids = get_device_ids(controller=in_args.host)
300 base_flow_ids = get_flow_ids(controller=in_args.host)
303 int(netaddr.IPAddress("10.0.0.1"))
304 ) # noqa # FIXME: This script seems to be unfinished!
306 preparefnc = _prepare_post # noqa # FIXME: This script seems to be unfinished!
309 print(" devices:", len(base_dev_ids))
310 print(" flows :", len(base_flow_ids))
312 # lets print some stats
313 print("\n\nSome stats monitoring ....")
314 print(get_flow_simple_stats(controller=in_args.host))
317 if __name__ == "__main__":