4 import flow_config_blaster
8 class FlowConfigBulkBlaster(flow_config_blaster.FlowConfigBlaster):
10 Reusing FlowConfigBlaster class providing flow operations based on bulk processing
13 FLW_ADD_RPC_URL = "restconf/operations/sal-bulk-flow:add-flows-rpc"
14 FLW_REMOVE_RPC_URL = "restconf/operations/sal-bulk-flow:remove-flows-rpc"
15 FLW_ADD_DS_URL = "restconf/operations/sal-bulk-flow:add-flows-ds"
16 FLW_REMOVE_DS_URL = "restconf/operations/sal-bulk-flow:remove-flows-ds"
18 def __init__(self, *args, **kwargs):
19 super(FlowConfigBulkBlaster, self).__init__(*args, **kwargs)
20 self.bulk_type = "RPC"
22 def update_post_url_template(self, action):
24 Update url templates (defined in parent class) in order to point to bulk API rpcs.
25 :param action: user intention (currently only 'ADD' is supported)
27 if self.bulk_type == "RPC":
28 self.post_url_template = "http://%s:" + self.port + "/"
30 self.post_url_template += self.FLW_ADD_RPC_URL
31 elif action == "REMOVE":
32 self.post_url_template += self.FLW_REMOVE_RPC_URL
33 elif self.bulk_type == "DS":
34 self.post_url_template = "http://%s:" + self.port + "/"
36 self.post_url_template += self.FLW_ADD_DS_URL
37 elif action == "REMOVE":
38 self.post_url_template += self.FLW_REMOVE_DS_URL
40 def assemble_post_url(self, host, node):
42 Format url to final form using substitutions. Here the node is ignored.
43 :param host: controller address
44 :param node: node identifier
45 :return: finalized url
47 return self.post_url_template % host
49 def create_flow_from_template(self, flow_id, ipaddr, node_id):
51 Create one flow beased on template and given values
52 :param flow_id: flow identifier
53 :param ipaddr: part of flow match
54 :param node_id: node identifier
55 :return: flow structure ready to use
57 # python 2.7 specific syntax (super)
58 flow = super(FlowConfigBulkBlaster, self).create_flow_from_template(
59 flow_id, ipaddr, node_id
63 if self.bulk_type == "DS":
64 flow["flow-id"] = flow_id
66 "/opendaylight-inventory:nodes/opendaylight-inventory"
67 ':node[opendaylight-inventory:id="openflow:{}"]'.format(node_id)
71 def convert_to_json(self, flow_list, node_id=None):
73 Converts given list of flows into string of json form.
74 :param flow_list: list of flows to convert
75 :param node_id: identifier of corresponding node
79 if self.bulk_type == "RPC":
80 json_input = {"input": {"bulk-flow-item": flow_list}}
81 elif self.bulk_type == "DS":
82 json_input = {"input": {"bulk-flow-ds-item": flow_list}}
84 flow_data = json.dumps(json_input)
88 if __name__ == "__main__":
89 ############################################################################
90 # This program executes the base performance test. The test adds flows into
91 # the controller's config space. This function is basically the CLI frontend
92 # to the FlowConfigBlaster class and drives its main functions: adding and
93 # deleting flows from the controller's config data store
94 ############################################################################
95 parser = flow_config_blaster.create_arguments_parser()
100 choices=["RPC", "DS"],
101 help="Bulk type to use: RPC, DS (default is RPC)",
104 in_args = parser.parse_args()
106 if in_args.file != "":
107 flow_template = flow_config_blaster.get_json_from_file(in_args.file)
111 fcbb = FlowConfigBulkBlaster(
122 fcbb.bulk_type = in_args.bulk_type
123 fcbb.update_post_url_template("ADD")
125 # Run through <cycles>, where <threads> are started in each cycle and
126 # <flows> are added from each thread
129 print("\n*** Total flows added: %s" % fcbb.get_ok_flows())
130 print(" HTTP[OK] results: %d\n" % fcbb.get_ok_rqsts())
132 if in_args.delay > 0:
134 "*** Waiting for %d seconds before the delete cycle ***\n" % in_args.delay
136 time.sleep(in_args.delay)
138 # Run through <cycles>, where <threads> are started in each cycle and
139 # <flows> previously added in an add cycle are deleted in each thread
141 fcbb.delete_blaster()
142 print("\n*** Total flows deleted: %s" % fcbb.get_ok_flows())
143 print(" HTTP[OK] results: %d\n" % fcbb.get_ok_rqsts())