+def _bulk_config_task_executor(preparefnc, flow_details=[], flow_template=None, controllers=['127.0.0.1'],
+ restport='8181', nrthreads=1, fpr=1):
+ '''Function starts thread executors and put required information to the queue. Executors read the queue and send
+ http requests. After the thread's join, it produces a summary result.'''
+ # TODO: multi controllers support
+ ip_addr = Counter(int(netaddr.IPAddress('10.0.0.1')))
+ if flow_template is not None:
+ template = flow_template
+ else:
+ template = _default_flow_template_json
+
+ # lets enlarge the tupple of flow details with IP, to be used with the template
+ flows = [(s, t, f, ip_addr.increment()) for s, t, f in flow_details]
+ # lest divide flows into switches and tables
+ fg = {}
+ for fl in flows:
+ s, t, f, ip = fl
+ fk = (s, t)
+ if (s, t) in fg:
+ fg[fk].append(fl)
+ else:
+ fg[fk] = [fl]
+
+ # lets fill the qurue
+ q = Queue.Queue()
+ for k, v in fg.iteritems():
+ while len(v) > 0:
+ q.put(v[:int(fpr)])
+ v = v[int(fpr):]
+
+ # result_gueue
+ rq = Queue.Queue()
+ # creaet exit event
+ ee = threading.Event()
+
+ # lets start threads whic will read flow details fro queues and send
+ threads = []
+ for i in range(int(nrthreads)):
+ t = threading.Thread(target=_wt_bulk_request_sender, args=(i, preparefnc),
+ kwargs={"inqueue": q, "exitevent": ee, "controllers": controllers, "restport": restport,
+ "template": template, "outqueue": rq})
+ threads.append(t)
+ t.start()
+
+ ee.set()
+
+ result = {}
+ # waitng for them
+ for t in threads:
+ t.join()
+ res = rq.get()
+ for k, v in res.iteritems():
+ if k not in result:
+ result[k] = v
+ else:
+ result[k] += v
+ return result
+
+
+def configure_flows_bulk(*args, **kwargs):
+ '''Configure flows based on given flow details
+ Input parameters with default values: preparefnc, flow_details=[], flow_template=None,
+ controllers=['127.0.0.1'], restport='8181', nrthreads=1'''
+ return _bulk_config_task_executor(_prepare_table_add, *args, **kwargs)
+
+