2 Documentation Keywords used to create/modify flow objects. The object is defined in the
3 ... corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
4 ... cookie and barrier fields, string formatted xml that can be used to push to
5 ... controller). TODO: Remove hard dependency on controller HTTP "session".
8 Library RequestsLibrary
11 Library XmlComparator.py
13 Variables ../variables/Variables.py
16 Check No Switches In Inventory
17 [Arguments] ${switches}
18 [Documentation] Check no switch is in inventory
19 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
21 Should Be Equal As Strings ${resp.status_code} 200
22 : FOR ${switch} IN RANGE 1 ${switches+1}
23 \ Should Not Contain ${resp.content} "openflow:${switch}"
25 Check No Switches In Topology
26 [Arguments] ${switches}
27 [Documentation] Check no switch is in topology
28 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
30 Should Be Equal As Strings ${resp.status_code} 200
31 : FOR ${switch} IN RANGE 1 ${switches+1}
32 \ Should Not Contain ${resp.content} openflow:${switch}
34 Check Switches In Inventory
35 [Arguments] ${switches}
36 [Documentation] Check all switches and stats in operational inventory
37 : FOR ${switch} IN RANGE 1 ${switches+1}
38 \ ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/openflow:${switch}
39 \ Should Be Equal As Strings ${resp.status_code} 200
40 \ Should Contain ${resp.content} flow-capable-node-connector-statistics
41 \ Should Contain ${resp.content} flow-table-statistics
43 Check Switches In Topology
44 [Arguments] ${switches}
45 [Documentation] Check switches are in the topology.
46 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
48 Should Be Equal As Strings ${resp.status_code} 200
49 ${count}= Get Count ${resp.content} "node-id":"openflow:
50 BuiltIn.Should Be Equal As Numbers ${count} ${switches}
54 [Documentation] Check number of links in the topolgy.
55 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
57 Should Be Equal As Strings ${resp.status_code} 200
58 ${count}= Get Count ${resp.content} "link-id":"openflow:
59 Should Be Equal As Integers ${count} ${links}
62 [Arguments] ${switches}
63 [Documentation] Check Linear topology.
64 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
66 Should Be Equal As Strings ${resp.status_code} 200
67 : FOR ${switch} IN RANGE 1 ${switches+1}
68 \ Should Contain ${resp.content} "node-id":"openflow:${switch}"
69 \ Should Contain ${resp.content} "tp-id":"openflow:${switch}:1"
70 \ Should Contain ${resp.content} "tp-id":"openflow:${switch}:2"
71 \ Should Contain ${resp.content} "source-tp":"openflow:${switch}:2"
72 \ Should Contain ${resp.content} "dest-tp":"openflow:${switch}:2"
73 \ ${edge} Evaluate ${switch}==1 or ${switch}==${switches}
74 \ Run Keyword Unless ${edge} Should Contain ${resp.content} "tp-id":"openflow:${switch}:3"
75 \ Run Keyword Unless ${edge} Should Contain ${resp.content} "source-tp":"openflow:${switch}:3"
76 \ Run Keyword Unless ${edge} Should Contain ${resp.content} "dest-tp":"openflow:${switch}:3"
78 Check Flows Operational Datastore
79 [Arguments] ${flow_count} ${controller_ip}=${ODL_SYSTEM_IP}
80 [Documentation] Check if number of Operational Flows on member of given index is equal to ${flow_count}.
81 ${sw} ${reported_flow} ${found_flow}= ScaleClient.Flow Stats Collected controller=${controller_ip}
82 Should_Be_Equal_As_Numbers ${flow_count} ${found_flow}
86 [Documentation] Check number of flows in the inventory.
87 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
89 Should Be Equal As Strings ${resp.status_code} 200
90 ${count}= Get Count ${resp.content} "priority"
91 Should Be Equal As Integers ${count} ${flows}
93 Check Number Of Groups
95 [Documentation] Check number of groups in the inventory.
96 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
98 Should Be Equal As Strings ${resp.status_code} 200
99 ${group_count}= Get Count ${resp.content} "group-type"
100 ${count}= CompareStream.Set_Variable_If_At Least_Boron ${group_count} ${group_count/2}
101 Should Be Equal As Integers ${count} ${groups}
103 Check Flow Stats Are Available
104 [Arguments] ${node_id} ${flows}
105 [Documentation] A GET on the /node/${node_id} inventory API is made and flow stats string is checked for existence.
106 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/${node_id}/table/2
108 Should Be Equal As Strings ${resp.status_code} 200
109 Should Contain X Times ${resp.content} priority ${flows}
111 Check Number Of Hosts
113 [Documentation] Check number of hosts in topology
114 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
116 Should Be Equal As Strings ${resp.status_code} 200
117 ${count}= Get Count ${resp.content} "node-id":"host:
118 Should Be Equal As Integers ${count} ${hosts}
121 [Documentation] Check if all hosts are deleted from inventory
122 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
123 Should Be Equal As Strings ${resp.status_code} 200
124 Should Not Contain ${resp.content} "node-id":"host:
127 [Arguments] ${switches}
128 [Documentation] Add table miss flows to switches.
129 ${switches}= Convert To Integer ${switches}
130 ${data}= OperatingSystem.Get File ${CURDIR}/../variables/openflowplugin/table_miss_flow.json
131 : FOR ${switch} IN RANGE 1 ${switches+1}
132 \ TemplatedRequests.Put As Json To Uri ${CONFIG_NODES_API}/node/openflow:${switch}/table/0/flow/default ${data} session
134 Check Table Miss Flows
135 [Arguments] ${switches}
136 [Documentation] Check table miss flows in switches.
137 ${switches}= Convert To Integer ${switches}
138 : FOR ${switch} IN RANGE 1 ${switches+1}
139 \ TemplatedRequests.Get As Json From Uri ${OPERATIONAL_NODES_API}/node/openflow:${switch}/table/0/flow/default session
141 Create Inventory Flow
142 [Documentation] Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
143 ... the basic flow elements that can be given to flow:inventory
144 ${flow}= Make Inventory Flow
148 [Documentation] Used for creating an object that will use an XML format that
149 ... can be given to flow:service.
150 ${flow}= Make Service Flow
153 Set "${flow}" "${property}" With "${property_val}"
154 [Documentation] Embedded variables to make higher level keywords more readable.
155 ... There are some cases where the python attribute uses an underscore,
156 ... but a hyphen needs to be used. This seems inconsistent, and may need
157 ... to be looked at from the openflow plugin perspective.
159 ... At this point, this library will remove the element ${property} from the
160 ... xml representation of the flow and reset with the given value. \ It's not
161 ... possible, yet, to have multiple elements with the same name. \ That will
162 ... likely be needed in the future.
163 ${property} Run Keyword If "table_id" != "${property}" and "cookie_mask" != "${property}" Replace String ${property} _ -
164 ... ELSE Set Variable ${property}
165 Remove Flow XML Element ${flow} ${property}
166 Add Flow XML Element ${flow} ${property} ${property_val}
167 Set Flow Field ${flow} ${property} ${property_val}
171 [Arguments] ${flow} ${instruction_order} ${action_order} ${action} ${action_val}=${EMPTY}
172 [Documentation] Will remove the instruction element first, then add the proper xml structure
173 ... to implement the action as given in the arguments
174 ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
175 Remove Flow XML Element ${flow} instruction
176 Add Flow XML Element ${flow} instruction ${EMPTY} instructions
177 Add Flow XML Element ${flow} order ${instruction_order} instructions/instruction
178 Add Flow XML Element ${flow} apply-actions ${EMPTY} instructions/instruction
179 Add Flow XML Element ${flow} action ${EMPTY} instructions/instruction/apply-actions
180 Add Flow XML Element ${flow} order ${action_order} instructions/instruction/apply-actions/action
181 Add Flow XML Element ${flow} ${action} ${action_val} instructions/instruction/apply-actions/action
184 Set Flow Output Action
185 [Arguments] ${flow} ${instruction_order} ${action_order} ${output_port}
186 Set Flow Action ${flow} ${instruction_order} ${action_order} output-action
187 Add Flow XML Element ${flow} output-node-connector ${output_port} instructions/instruction/apply-actions/action/output-action
190 Set Flow Ethernet Match
191 [Arguments] ${flow} ${match_value_dict}
192 [Documentation] Specific keyword for adding an ethernet match rules where the elements are given
193 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
194 ... existing ethernet-match elements from the flow before adding
195 Clear Flow Matches ${flow} match/ethernet-match
196 Add Flow XML Element ${flow} ethernet-match ${EMPTY} match
197 ${type}= Get From Dictionary ${match_value_dict} type
198 Add Flow XML Element ${flow} ethernet-type ${EMPTY} match/ethernet-match
199 Add Flow XML Element ${flow} type ${type} match/ethernet-match/ethernet-type
200 ${src}= Get From Dictionary ${match_value_dict} source
201 Add Flow XML Element ${flow} ethernet-source ${EMPTY} match/ethernet-match
202 Add Flow XML Element ${flow} address ${src} match/ethernet-match/ethernet-source
203 ${dst}= Get From Dictionary ${match_value_dict} destination
204 Add Flow XML Element ${flow} ethernet-destination ${EMPTY} match/ethernet-match
205 Add Flow XML Element ${flow} address ${dst} match/ethernet-match/ethernet-destination
209 [Arguments] ${flow} ${match_value_dict}
210 [Documentation] Specific keyword for adding an ipv4 match rules where the elements are given
211 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
212 ... existing ipv4 match elements from the flow before adding
213 Clear Flow Matches ${flow} match/ipv4-source
214 Clear Flow Matches ${flow} match/ipv4-destination
215 ${src}= Get From Dictionary ${match_value_dict} source
216 Add Flow XML Element ${flow} ipv4-source ${src} match
217 ${dst}= Get From Dictionary ${match_value_dict} destination
218 Add Flow XML Element ${flow} ipv4-destination ${dst} match
223 [Documentation] Will clean out any existing flow actions in the given ${flow} object
224 Remove Flow XML Element ${flow} instructions/instruction
228 [Arguments] ${flow} ${match_element}
229 [Documentation] Will clean out any existing flow matches in the given ${flow} object
230 Remove Flow XML Element ${flow} match/${match_element}
233 Set Flow XML Element Attribute
234 [Arguments] ${flow} ${element} ${id} ${value}
235 [Documentation] Will set the given id/value pair to the given to the element provided
236 ... and make the proper changes to the ${flow} object also provided.
237 ${flow_xml}= Parse XML ${flow.xml}
238 Set Element Attribute ${flow_xml} ${id} ${value} xpath=${element}
239 ${xml_string}= Element To String ${flow_xml}
240 Set Flow Field ${flow} xml ${xml_string}
245 [Arguments] ${flow} ${element} ${element_val}=${EMPTY} ${xpath}=.
246 [Documentation] Will modify the current xml representation of the ${flow} object to contain
247 ... the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
248 ... passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
249 ... are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
250 ... you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
251 ... location in the parameter list
252 ${flow_xml}= Parse XML ${flow.xml}
253 Add Element ${flow_xml} <${element}>${element_val}</${element}> xpath=${xpath}
254 ${xml_string}= Element To String ${flow_xml}
255 Set Flow Field ${flow} xml ${xml_string}
259 Remove Flow XML Element
260 [Arguments] ${flow} ${element_xpath}
261 [Documentation] Removes the element at the given ${element_xpath} within the given ${flow}
262 ... object. The ${flow} object's xml representation will be updated to reflect this removal.
263 ${flow_xml}= Parse XML ${flow.xml}
264 Run Keyword And Ignore Error Remove Elements ${flow_xml} xpath=${element_xpath}
265 ${xml_string}= Element To String ${flow_xml}
266 Set Flow Field ${flow} xml ${xml_string}
269 Add Group To Controller And Verify
270 [Arguments] ${group_body} ${node_id} ${group_id}
271 [Documentation] Push group through REST-API and verify in data-store
272 ${resp} RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id} headers=${HEADERS_XML} data=${group_body}
274 BuiltIn.Should_Match "${resp.status_code}" "20?"
275 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id} headers=${ACCEPT_XML}
277 Should Be Equal As Strings ${resp.status_code} 200
278 Compare Xml ${group_body} ${resp.content}
280 Add Flow To Controller And Verify
281 [Arguments] ${flow_body} ${node_id} ${table_id} ${flow_id}
282 [Documentation] Push flow through REST-API and verify in data-store
283 ${resp} RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${HEADERS_XML} data=${flow_body}
285 BuiltIn.Should_Match "${resp.status_code}" "20?"
286 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${ACCEPT_XML}
288 Should Be Equal As Strings ${resp.status_code} 200
289 Compare Xml ${flow_body} ${resp.content}
291 Verify Flow On Mininet Switch
292 [Arguments] ${flow_elements}
293 [Documentation] Checking flow on switch
295 Write dpctl dump-flows -O OpenFlow13
296 ${switchoutput} Read Until >
297 : FOR ${flowElement} IN @{flow_elements}
298 \ Should Contain ${switchoutput} ${flowElement}
300 Remove Group From Controller And Verify
301 [Arguments] ${node_id} ${group_id}
302 [Documentation] Remove group and verify
303 ${resp} RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
305 Should Be Equal As Strings ${resp.status_code} 200
306 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
307 Builtin.Return_From_Keyword_If ${resp.status_code} == 404
308 Builtin.Log ${resp.text}
309 Builtin.Fail The request failed with code ${resp.status_code}
311 Remove Flow From Controller And Verify
312 [Arguments] ${node_id} ${table_id} ${flow_id}
313 [Documentation] Remove flow and verify
314 ${resp} RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
316 Should Be Equal As Strings ${resp.status_code} 200
317 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
318 Builtin.Return_From_Keyword_If ${resp.status_code} == 404
319 Builtin.Log ${resp.text}
320 Builtin.Fail The request failed with code ${resp.status_code}
322 Verify Flow Does Not Exist On Mininet Switch
323 [Arguments] ${flow_elements}
324 [Documentation] Checking flow on switch is removed
326 Write dpctl dump-flows -O OpenFlow13
327 ${switchoutput} Read Until >
328 : FOR ${flowElement} IN @{flow_elements}
329 \ Should Not Contain ${switchoutput} ${flowElement}
332 [Arguments] ${node_id}
333 [Documentation] Removes any flows considered "default". one such flow is
334 ... to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
335 ... If/When others are implemented this keyword can be updated to include those.
336 ${flow}= Make Service Flow
337 Set "${flow}" "priority" With "0"
338 Set "${flow}" "flow-table" With "0"
339 Add Flow XML Element ${flow} node /inv:nodes/inv:node[inv:id="${node_id}"]
340 Set Flow XML Element Attribute ${flow} node xmlns:inv urn:opendaylight:inventory
341 Log Flow XML is ${flow.xml}
342 write dpctl dump-flows -O OpenFlow13
343 ${switchoutput} Read Until >
344 ${headers}= Create Dictionary Content-Type=application/yang.data+xml
345 ${resp} RequestsLibrary.Post Request session restconf/operations/sal-flow:remove-flow data=${flow.xml} headers=${headers}
347 Should Be Equal As Strings ${resp.status_code} 200
348 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
350 Should Not Contain ${resp.content} "output-node-connector": "CONTROLLER",
351 ${strings_to_check_for}= Create List CONTROLLER
352 Verify Flow Does Not Exist On Mininet Switch ${strings_to_check_for}
354 Create Flow Variables For Suite From XML File
356 [Documentation] Given the flow XML ${file}, it will create several suite wide variables
357 ${data}= OperatingSystem.Get File ${file}
358 ${xmlroot}= Parse Xml ${file}
359 ${table_id}= Get Element Text ${xmlroot} table_id
360 ${flow_id}= Get Element Text ${xmlroot} id
361 ${flow_priority}= Get Element Text ${xmlroot} priority
362 ${upddata}= Get Data For Flow Put Update ${data}
363 Set Suite Variable ${table_id}
364 Set Suite Variable ${flow_id}
365 Set Suite Variable ${flow_priority}
366 Set Suite Variable ${data}
367 Set Suite Variable ${upddata}
368 Set Suite Variable ${xmlroot}
370 Check Datastore Presence
371 [Arguments] ${fname} ${reqconfpres} ${reqoperpres} ${upd} ${check_id}=${False}
372 [Documentation] Checks if flow is properly existing or not existing in the config and operational
373 ... datastores, based on the variables ${reqconfpres} and ${reqoperpres}
374 Create Flow Variables For Suite From XML File ${XmlsDir}/${fname}
375 # Note: ${upddata} and ${data} are suite variables set by the keyword above.
376 ${det}= Set Variable If ${upd}==${True} ${upddata} ${data}
377 Check Config Flow ${reqconfpres} ${det}
378 Check Operational Flow ${reqoperpres} ${det} ${check_id}
380 Flow Presence In Config Store
381 [Arguments] ${expvalue}
382 [Documentation] Checks the config store for given flow. Returns True if present, otherwise returns False
383 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
384 ${headers}= Create Dictionary Accept=application/xml
385 ${resp}= RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id} headers=${headers}
388 Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
389 ${pres} ${msg}= Is Flow Configured ${expvalue} ${resp.content}
390 Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
391 Return From Keyword ${pres} ${msg}
393 Flow Presence In Operational Store
394 [Arguments] ${expvalue} ${check_id}=${False}
395 [Documentation] Checks the operational store for given flow. Returns True if present, otherwise returns False
396 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
397 ${headers}= Create Dictionary Accept=application/xml
398 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id} headers=${headers}
401 Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
402 ${pres} ${msg}= Is Flow Operational2 ${expvalue} ${resp.content} ${check_id}
403 Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
404 Return From Keyword ${pres} ${msg}
406 Get Presence Failure Message
407 [Arguments] ${ds} ${expected} ${presence} ${diffmsg}
408 [Documentation] Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
409 Return From Keyword If '''${diffmsg}'''!='${EMPTY}' Flow found in ${ds} data store but: ${diffmsg}
410 ${msgf}= Set Variable If ${expected}==${True} The flow is expected in ${ds} data store, but The flow is not expected in ${ds} data store, but
411 ${msgp}= Set Variable If ${presence}==${True} it is present. it is not present.
412 Return From Keyword ${msgf} ${msgp}
415 [Arguments] ${expected} ${expvalue}
416 [Documentation] Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
417 ... to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
418 ${presence_flow} ${msg}= Flow Presence In Config Store ${expvalue}
419 ${msgf}= Get Presence Failure Message config ${expected} ${presence_flow} ${msg}
420 Should Be Equal ${expected} ${presence_flow} msg=${msgf}
422 Check Operational Flow
423 [Arguments] ${expected} ${expvalue} ${check_id}=${False}
424 [Documentation] Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
425 ... to verify that the ${expvalue} flow is or is not found in the operational store, depending on whether or not it was ${expected}
426 ${presence_table} ${msg}= Flow Presence In Operational Store ${expvalue} ${check_id}
427 ${msgf}= Get Presence Failure Message operational ${expected} ${presence_table} ${msg}
428 Should Be Equal ${expected} ${presence_table} msg=${msgf}
431 [Arguments] ${node_id} ${xmlroot}
432 [Documentation] Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
433 ... ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
434 ... keyword from this library.
435 ${req}= Copy Element ${xmlroot}
436 Remove Element ${req} id clear_tail=True
437 Set Element Tag ${req} input
438 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
439 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
440 ${nodeelm}= Get Element ${req} node
441 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
443 ${strxml}= Element To String ${req}
444 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:add-flow data=${strxml}
446 Should Be Equal As Strings ${resp.status_code} 200
448 Add Flow Via Restconf
449 [Arguments] ${node_id} ${table_id} ${flow_body}
450 [Documentation] Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
452 ${resp}= RequestsLibrary.Post Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} data=${flow_body}
454 ${msg}= Set Variable Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
455 Should Be Equal As Strings ${resp.status_code} 204 msg=${msg}
458 [Arguments] ${node_id} ${configured_flow_body} ${updating_flow_body}
459 [Documentation] Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
460 ... Create Flow Variables For Suite From XML File keyword from this library.
461 Log ${configured_flow_body}
462 Log ${updating_flow_body}
463 ${xml} Parse Xml <input xmlns="urn:opendaylight:flow:service"></input>
465 ${origflow}= Parse Xml ${configured_flow_body}
466 ${updflow}= Parse Xml ${updating_flow_body}
467 Remove Element ${origflow} id clear_tail=True
468 Remove Element ${updflow} id clear_tail=True
469 Remove Element Attribute ${origflow} xmlns
470 Remove Element Attribute ${updflow} xmlns
471 Set Element Tag ${origflow} original-flow
472 Set Element Tag ${updflow} updated-flow
473 Add Element ${xml} ${origflow}
474 Add Element ${xml} ${updflow}
475 Add Element ${xml} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
476 ${nodeelm}= Get Element ${xml} node
477 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
479 ${strxml}= Element To String ${xml}
480 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:update-flow data=${strxml}
482 Should Be Equal As Strings ${resp.status_code} 200
484 Update Flow Via Restconf
485 [Arguments] ${node_id} ${table_id} ${flow_id} ${flow_body}
486 [Documentation] Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
488 ${resp}= RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} data=${flow_body}
490 ${msg}= Set Variable Updating flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
491 Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}
494 [Arguments] ${node_id} ${xmlroot}
495 [Documentation] Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
496 ... Create Flow Variables For Suite From XML File keyword from this library.
497 ${req}= Copy Element ${xmlroot}
498 Remove Element ${req} id clear_tail=True
499 Set Element Tag ${req} input
500 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
501 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
502 ${nodeelm}= Get Element ${req} node
503 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
505 ${strxml}= Element To String ${req}
506 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:remove-flow data=${strxml}
508 Should Be Equal As Strings ${resp.status_code} 200
510 Delete Flow Via Restconf
511 [Arguments] ${node_id} ${table_id} ${flow_id}
512 [Documentation] Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
513 ${resp}= RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
515 ${msg}= Set Variable Delete flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
516 Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}