5 from xml.etree import ElementTree as ET
7 from openvswitch.flow_tools import TO_GET, OPERATIONAL_DELAY, FLOWS_PER_SECOND
10 class GetFlowsComponent():
12 log = logging.getLogger('GetFlowsComponent')
15 def get_flows(host, port, store='config'):
16 url = 'http://%s:%d/restconf/%s/opendaylight-inventory:nodes' \
17 '/node/openflow:1/table/2/' % (host, port, store)
18 GetFlowsComponent.log.debug('checking flows in controller - sending request to url: {0}'.format(url))
19 response = requests.get(url, auth=('admin', 'admin'),
20 headers={'Accept': 'application/xml'}, timeout=TO_GET)
23 class CheckSwitchDump():
25 log = logging.getLogger('CheckSwitchDump')
27 def get_id_by_entry(self, dump_flow, id_map):
31 cookie_regexp = re.compile("cookie=0x[0-9,a-f,A-F]+")
32 cookie_match = re.search(cookie_regexp, dump_flow)
33 if cookie_match is not None:
34 cookie_id = cookie_match.group(0)[7:-1]
35 flow_id = id_map[cookie_id]
37 CheckSwitchDump.log.info('skipping parsing dump entry: {0} '.format(dump_flow))
40 CheckSwitchDump.log.error('cookie: {0} is not contained in stored flows'.format(cookie_id))
41 except StandardError as e:
42 CheckSwitchDump.log.error('problem getting stored flow flow_id from cookie from flow dump:{0} reason:{1}'.format(dump_flow, str(e)))
47 class CheckConfigFlowsComponent():
49 log = logging.getLogger('CheckConfigFlowsComponent')
51 def check_config_flows(self, host, port, id_map):
54 response = GetFlowsComponent.get_flows(host, port)
55 assert response.status_code == 200, 'response from config must be 200, is {0}'.format(response.status_code)
56 tree = ET.ElementTree(ET.fromstring(response.text))
58 return GetXMLFlowsComponent.get_xml_flows_by_map(tree.getroot(), id_map)
59 except StandardError as e:
60 CheckConfigFlowsComponent.log.error('problem getting flows from config: {0}'.format(str(e)))
64 class CheckOperFlowsComponent():
66 log = logging.getLogger('CheckOperFlowsComponent')
68 def check_oper_flows(self, host, port, id_map, wait_time=OPERATIONAL_DELAY):
72 response = GetFlowsComponent.get_flows(host, port, 'operational')
73 assert response.status_code == 200, 'response from config must be 200, is {0}'.format(response.status_code)
74 CheckOperFlowsComponent.log.debug('got resposnse: {0}'.format(response.status_code))
75 CheckOperFlowsComponent.log.debug('operational dump:\n{0}'.format(response.text))
77 tree = ET.ElementTree(ET.fromstring(response.text))
80 return GetXMLFlowsComponent.get_xml_flows_by_map(tree.getroot(), id_map)
81 except StandardError as e:
82 CheckOperFlowsComponent.log.error('problem getting flows from operational: {0}'.format(str(e)))
85 def check_oper_flows_loop(self, host, port, id_map, max_tries=2):
86 # determine how much time we will wait for flows to get on switch
87 target_oper_flows = len(id_map)
89 current_oper_flows = 0
91 wait_for_flows = (target_oper_flows / FLOWS_PER_SECOND) + OPERATIONAL_DELAY
93 #check operational - in loop for determined number of tries
94 while current_oper_flows < target_oper_flows and max_tries > current_try:
95 CheckOperFlowsComponent.log.info('checking operational... waiting {0} seconds, {1}/{2}'.format(wait_for_flows, current_try + 1, max_tries))
96 current_oper_flows = self.check_oper_flows(host, port, id_map, wait_for_flows)
97 CheckOperFlowsComponent.log.info('got {0} flows on {1}. try'.format(current_oper_flows, current_try + 1))
99 return current_oper_flows
101 class GetXMLFlowsComponent():
104 def get_xml_flows_by_map(xml_tree, id_map, namespace='{urn:opendaylight:flow:inventory}'):
107 for e in xml_tree.findall(namespace + 'flow'):
108 xml_id = int(e.find(namespace + 'id').text)
110 if xml_id in id_map.values():