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}
20 Should Be Equal As Strings ${resp.status_code} 200
21 : FOR ${switch} IN RANGE 1 ${switches+1}
22 \ Should Not Contain ${resp.content} "openflow:${switch}"
24 Check No Switches In Topology
25 [Arguments] ${switches}
26 [Documentation] Check no switch is in topology
27 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
28 Should Be Equal As Strings ${resp.status_code} 200
29 : FOR ${switch} IN RANGE 1 ${switches+1}
30 \ Should Not Contain ${resp.content} openflow:${switch}
32 Check Switches In Inventory
33 [Arguments] ${switches}
34 [Documentation] Check all switches and stats in operational inventory
35 ${mac}= String.Replace String Using Regexp ${base_mac} : ${EMPTY}
36 ${mac}= Evaluate int(${mac}, 16)
37 : FOR ${switch} IN RANGE 1 ${switches+1}
38 \ ${dpid_decimal}= Evaluate ${mac} + ${switch}
39 \ ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/openflow:${dpid_decimal}
40 \ Should Be Equal As Strings ${resp.status_code} 200
41 \ Should Contain ${resp.content} flow-capable-node-connector-statistics
42 \ Should Contain ${resp.content} flow-table-statistics
44 Check Switches In Topology
45 [Arguments] ${switches}
46 [Documentation] Check switches are in the topology.
47 ${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}
56 Should Be Equal As Strings ${resp.status_code} 200
57 ${count}= Get Count ${resp.content} "link-id":"openflow:
58 Should Be Equal As Integers ${count} ${links}
61 [Arguments] ${switches}
62 [Documentation] Check Linear topology.
63 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
64 Should Be Equal As Strings ${resp.status_code} 200
65 : FOR ${switch} IN RANGE 1 ${switches+1}
66 \ Should Contain ${resp.content} "node-id":"openflow:${switch}"
67 \ Should Contain ${resp.content} "tp-id":"openflow:${switch}:1"
68 \ Should Contain ${resp.content} "tp-id":"openflow:${switch}:2"
69 \ Should Contain ${resp.content} "source-tp":"openflow:${switch}:2"
70 \ Should Contain ${resp.content} "dest-tp":"openflow:${switch}:2"
71 \ ${edge} Evaluate ${switch}==1 or ${switch}==${switches}
72 \ Run Keyword Unless ${edge} Should Contain ${resp.content} "tp-id":"openflow:${switch}:3"
73 \ Run Keyword Unless ${edge} Should Contain ${resp.content} "source-tp":"openflow:${switch}:3"
74 \ Run Keyword Unless ${edge} Should Contain ${resp.content} "dest-tp":"openflow:${switch}:3"
76 Check Flows Operational Datastore
77 [Arguments] ${flow_count} ${controller_ip}=${ODL_SYSTEM_IP}
78 [Documentation] Check if number of Operational Flows on member of given index is equal to ${flow_count}.
79 ${sw} ${reported_flow} ${found_flow}= ScaleClient.Flow Stats Collected controller=${controller_ip}
80 Should_Be_Equal_As_Numbers ${flow_count} ${found_flow}
84 [Documentation] Check number of flows in the inventory.
85 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
86 Should Be Equal As Strings ${resp.status_code} 200
87 ${count}= Get Count ${resp.content} "priority"
88 Should Be Equal As Integers ${count} ${flows}
90 Check Number Of Groups
92 [Documentation] Check number of groups in the inventory.
93 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
94 Should Be Equal As Strings ${resp.status_code} 200
95 ${group_count}= Get Count ${resp.content} "group-type"
96 ${count}= CompareStream.Set_Variable_If_At Least_Boron ${group_count} ${group_count/2}
97 Should Be Equal As Integers ${count} ${groups}
99 Check Flow Stats Are Available
100 [Arguments] ${node_id} ${flows}
101 [Documentation] A GET on the /node/${node_id} inventory API is made and flow stats string is checked for existence.
102 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/${node_id}/table/2
104 Should Be Equal As Strings ${resp.status_code} 200
105 Should Contain X Times ${resp.content} priority ${flows}
107 Create Inventory Flow
108 [Documentation] Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
109 ... the basic flow elements that can be given to flow:inventory
110 ${flow}= Make Inventory Flow
114 [Documentation] Used for creating an object that will use an XML format that
115 ... can be given to flow:service.
116 ${flow}= Make Service Flow
119 Set "${flow}" "${property}" With "${property_val}"
120 [Documentation] Embedded variables to make higher level keywords more readable.
121 ... There are some cases where the python attribute uses an underscore,
122 ... but a hyphen needs to be used. This seems inconsistent, and may need
123 ... to be looked at from the openflow plugin perspective.
125 ... At this point, this library will remove the element ${property} from the
126 ... xml representation of the flow and reset with the given value. \ It's not
127 ... possible, yet, to have multiple elements with the same name. \ That will
128 ... likely be needed in the future.
129 ${property} Run Keyword If "table_id" != "${property}" and "cookie_mask" != "${property}" Replace String ${property} _ -
130 ... ELSE Set Variable ${property}
131 Remove Flow XML Element ${flow} ${property}
132 Add Flow XML Element ${flow} ${property} ${property_val}
133 Set Flow Field ${flow} ${property} ${property_val}
137 [Arguments] ${flow} ${instruction_order} ${action_order} ${action} ${action_val}=${EMPTY}
138 [Documentation] Will remove the instruction element first, then add the proper xml structure
139 ... to implement the action as given in the arguments
140 ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
141 Remove Flow XML Element ${flow} instruction
142 Add Flow XML Element ${flow} instruction ${EMPTY} instructions
143 Add Flow XML Element ${flow} order ${instruction_order} instructions/instruction
144 Add Flow XML Element ${flow} apply-actions ${EMPTY} instructions/instruction
145 Add Flow XML Element ${flow} action ${EMPTY} instructions/instruction/apply-actions
146 Add Flow XML Element ${flow} order ${action_order} instructions/instruction/apply-actions/action
147 Add Flow XML Element ${flow} ${action} ${action_val} instructions/instruction/apply-actions/action
150 Set Flow Output Action
151 [Arguments] ${flow} ${instruction_order} ${action_order} ${output_port}
152 Set Flow Action ${flow} ${instruction_order} ${action_order} output-action
153 Add Flow XML Element ${flow} output-node-connector ${output_port} instructions/instruction/apply-actions/action/output-action
156 Set Flow Ethernet Match
157 [Arguments] ${flow} ${match_value_dict}
158 [Documentation] Specific keyword for adding an ethernet match rules where the elements are given
159 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
160 ... existing ethernet-match elements from the flow before adding
161 Clear Flow Matches ${flow} match/ethernet-match
162 Add Flow XML Element ${flow} ethernet-match ${EMPTY} match
163 ${type}= Get From Dictionary ${match_value_dict} type
164 Add Flow XML Element ${flow} ethernet-type ${EMPTY} match/ethernet-match
165 Add Flow XML Element ${flow} type ${type} match/ethernet-match/ethernet-type
166 ${src}= Get From Dictionary ${match_value_dict} source
167 Add Flow XML Element ${flow} ethernet-source ${EMPTY} match/ethernet-match
168 Add Flow XML Element ${flow} address ${src} match/ethernet-match/ethernet-source
169 ${dst}= Get From Dictionary ${match_value_dict} destination
170 Add Flow XML Element ${flow} ethernet-destination ${EMPTY} match/ethernet-match
171 Add Flow XML Element ${flow} address ${dst} match/ethernet-match/ethernet-destination
175 [Arguments] ${flow} ${match_value_dict}
176 [Documentation] Specific keyword for adding an ipv4 match rules where the elements are given
177 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
178 ... existing ipv4 match elements from the flow before adding
179 Clear Flow Matches ${flow} match/ipv4-source
180 Clear Flow Matches ${flow} match/ipv4-destination
181 ${src}= Get From Dictionary ${match_value_dict} source
182 Add Flow XML Element ${flow} ipv4-source ${src} match
183 ${dst}= Get From Dictionary ${match_value_dict} destination
184 Add Flow XML Element ${flow} ipv4-destination ${dst} match
189 [Documentation] Will clean out any existing flow actions in the given ${flow} object
190 Remove Flow XML Element ${flow} instructions/instruction
194 [Arguments] ${flow} ${match_element}
195 [Documentation] Will clean out any existing flow matches in the given ${flow} object
196 Remove Flow XML Element ${flow} match/${match_element}
199 Set Flow XML Element Attribute
200 [Arguments] ${flow} ${element} ${id} ${value}
201 [Documentation] Will set the given id/value pair to the given to the element provided
202 ... and make the proper changes to the ${flow} object also provided.
203 ${flow_xml}= Parse XML ${flow.xml}
204 Set Element Attribute ${flow_xml} ${id} ${value} xpath=${element}
205 ${xml_string}= Element To String ${flow_xml}
206 Set Flow Field ${flow} xml ${xml_string}
211 [Arguments] ${flow} ${element} ${element_val}=${EMPTY} ${xpath}=.
212 [Documentation] Will modify the current xml representation of the ${flow} object to contain
213 ... the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
214 ... passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
215 ... are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
216 ... you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
217 ... location in the parameter list
218 ${flow_xml}= Parse XML ${flow.xml}
219 Add Element ${flow_xml} <${element}>${element_val}</${element}> xpath=${xpath}
220 ${xml_string}= Element To String ${flow_xml}
221 Set Flow Field ${flow} xml ${xml_string}
225 Remove Flow XML Element
226 [Arguments] ${flow} ${element_xpath}
227 [Documentation] Removes the element at the given ${element_xpath} within the given ${flow}
228 ... object. The ${flow} object's xml representation will be updated to reflect this removal.
229 ${flow_xml}= Parse XML ${flow.xml}
230 Run Keyword And Ignore Error Remove Elements ${flow_xml} xpath=${element_xpath}
231 ${xml_string}= Element To String ${flow_xml}
232 Set Flow Field ${flow} xml ${xml_string}
235 Add Group To Controller And Verify
236 [Arguments] ${group_body} ${node_id} ${group_id}
237 [Documentation] Push group through REST-API and verify in data-store
238 ${resp} RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id} headers=${HEADERS_XML} data=${group_body}
240 BuiltIn.Should_Match "${resp.status_code}" "20?"
241 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id} headers=${ACCEPT_XML}
243 Should Be Equal As Strings ${resp.status_code} 200
244 Compare Xml ${group_body} ${resp.content}
246 Add Flow To Controller And Verify
247 [Arguments] ${flow_body} ${node_id} ${table_id} ${flow_id}
248 [Documentation] Push flow through REST-API and verify in data-store
249 ${resp} RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${HEADERS_XML} data=${flow_body}
251 BuiltIn.Should_Match "${resp.status_code}" "20?"
252 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${ACCEPT_XML}
254 Should Be Equal As Strings ${resp.status_code} 200
255 Compare Xml ${flow_body} ${resp.content}
257 Verify Flow On Mininet Switch
258 [Arguments] ${flow_elements}
259 [Documentation] Checking flow on switch
261 Write dpctl dump-flows -O OpenFlow13
262 ${switchoutput} Read Until >
263 : FOR ${flowElement} IN @{flow_elements}
264 \ Should Contain ${switchoutput} ${flowElement}
266 Remove Group From Controller And Verify
267 [Arguments] ${node_id} ${group_id}
268 [Documentation] Remove group and verify
269 ${resp} RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
271 Should Be Equal As Strings ${resp.status_code} 200
272 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
273 Builtin.Return_From_Keyword_If ${resp.status_code} == 404
274 Builtin.Log ${resp.text}
275 Builtin.Fail The request failed with code ${resp.status_code}
277 Remove Flow From Controller And Verify
278 [Arguments] ${node_id} ${table_id} ${flow_id}
279 [Documentation] Remove flow and verify
280 ${resp} RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
282 Should Be Equal As Strings ${resp.status_code} 200
283 ${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
284 Builtin.Return_From_Keyword_If ${resp.status_code} == 404
285 Builtin.Log ${resp.text}
286 Builtin.Fail The request failed with code ${resp.status_code}
288 Verify Flow Does Not Exist On Mininet Switch
289 [Arguments] ${flow_elements}
290 [Documentation] Checking flow on switch is removed
292 Write dpctl dump-flows -O OpenFlow13
293 ${switchoutput} Read Until >
294 : FOR ${flowElement} IN @{flow_elements}
295 \ Should Not Contain ${switchoutput} ${flowElement}
298 [Arguments] ${node_id}
299 [Documentation] Removes any flows considered "default". one such flow is
300 ... to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
301 ... If/When others are implemented this keyword can be updated to include those.
302 ${flow}= Make Service Flow
303 Set "${flow}" "priority" With "0"
304 Set "${flow}" "flow-table" With "0"
305 Add Flow XML Element ${flow} node /inv:nodes/inv:node[inv:id="${node_id}"]
306 Set Flow XML Element Attribute ${flow} node xmlns:inv urn:opendaylight:inventory
307 Log Flow XML is ${flow.xml}
308 write dpctl dump-flows -O OpenFlow13
309 ${switchoutput} Read Until >
310 ${headers}= Create Dictionary Content-Type=application/yang.data+xml
311 ${resp} RequestsLibrary.Post Request session restconf/operations/sal-flow:remove-flow data=${flow.xml} headers=${headers}
313 Should Be Equal As Strings ${resp.status_code} 200
314 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
316 Should Not Contain ${resp.content} "output-node-connector": "CONTROLLER",
317 ${strings_to_check_for}= Create List CONTROLLER
318 Verify Flow Does Not Exist On Mininet Switch ${strings_to_check_for}
320 Create Flow Variables For Suite From XML File
322 [Documentation] Given the flow XML ${file}, it will create several suite wide variables
323 ${data}= OperatingSystem.Get File ${file}
324 ${xmlroot}= Parse Xml ${file}
325 ${table_id}= Get Element Text ${xmlroot} table_id
326 ${flow_id}= Get Element Text ${xmlroot} id
327 ${flow_priority}= Get Element Text ${xmlroot} priority
328 ${upddata}= Get Data For Flow Put Update ${data}
329 Set Suite Variable ${table_id}
330 Set Suite Variable ${flow_id}
331 Set Suite Variable ${flow_priority}
332 Set Suite Variable ${data}
333 Set Suite Variable ${upddata}
334 Set Suite Variable ${xmlroot}
336 Check Datastore Presence
337 [Arguments] ${fname} ${reqconfpres} ${reqoperpres} ${upd} ${check_id}=${False}
338 [Documentation] Checks if flow is properly existing or not existing in the config and operational
339 ... datastores, based on the variables ${reqconfpres} and ${reqoperpres}
340 Create Flow Variables For Suite From XML File ${XmlsDir}/${fname}
341 # Note: ${upddata} and ${data} are suite variables set by the keyword above.
342 ${det}= Set Variable If ${upd}==${True} ${upddata} ${data}
343 Check Config Flow ${reqconfpres} ${det}
344 Check Operational Flow ${reqoperpres} ${det} ${check_id}
346 Flow Presence In Config Store
347 [Arguments] ${expvalue}
348 [Documentation] Checks the config store for given flow. Returns True if present, otherwise returns False
349 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
350 ${headers}= Create Dictionary Accept=application/xml
351 ${resp}= RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id} headers=${headers}
354 Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
355 ${pres} ${msg}= Is Flow Configured ${expvalue} ${resp.content}
356 Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
357 Return From Keyword ${pres} ${msg}
359 Flow Presence In Operational Store
360 [Arguments] ${expvalue} ${check_id}=${False}
361 [Documentation] Checks the operational store for given flow. Returns True if present, otherwise returns False
362 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
363 ${headers}= Create Dictionary Accept=application/xml
364 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id} headers=${headers}
367 Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
368 ${pres} ${msg}= Is Flow Operational2 ${expvalue} ${resp.content} ${check_id}
369 Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
370 Return From Keyword ${pres} ${msg}
372 Get Presence Failure Message
373 [Arguments] ${ds} ${expected} ${presence} ${diffmsg}
374 [Documentation] Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
375 Return From Keyword If '''${diffmsg}'''!='${EMPTY}' Flow found in ${ds} data store but: ${diffmsg}
376 ${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
377 ${msgp}= Set Variable If ${presence}==${True} it is present. it is not present.
378 Return From Keyword ${msgf} ${msgp}
381 [Arguments] ${expected} ${expvalue}
382 [Documentation] Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
383 ... to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
384 ${presence_flow} ${msg}= Flow Presence In Config Store ${expvalue}
385 ${msgf}= Get Presence Failure Message config ${expected} ${presence_flow} ${msg}
386 Should Be Equal ${expected} ${presence_flow} msg=${msgf}
388 Check Operational Flow
389 [Arguments] ${expected} ${expvalue} ${check_id}=${False}
390 [Documentation] Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
391 ... to verify that the ${expvalue} flow is or is not found in the operational store, depending on whether or not it was ${expected}
392 ${presence_table} ${msg}= Flow Presence In Operational Store ${expvalue} ${check_id}
393 ${msgf}= Get Presence Failure Message operational ${expected} ${presence_table} ${msg}
394 Should Be Equal ${expected} ${presence_table} msg=${msgf}
397 [Arguments] ${node_id} ${xmlroot}
398 [Documentation] Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
399 ... ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
400 ... keyword from this library.
401 ${req}= Copy Element ${xmlroot}
402 Remove Element ${req} id clear_tail=True
403 Set Element Tag ${req} input
404 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
405 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
406 ${nodeelm}= Get Element ${req} node
407 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
409 ${strxml}= Element To String ${req}
410 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:add-flow data=${strxml}
412 Should Be Equal As Strings ${resp.status_code} 200
414 Add Flow Via Restconf
415 [Arguments] ${node_id} ${table_id} ${flow_body}
416 [Documentation] Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
418 ${resp}= RequestsLibrary.Post Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} data=${flow_body}
420 ${msg}= Set Variable Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
421 Should Be Equal As Strings ${resp.status_code} 204 msg=${msg}
424 [Arguments] ${node_id} ${configured_flow_body} ${updating_flow_body}
425 [Documentation] Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
426 ... Create Flow Variables For Suite From XML File keyword from this library.
427 Log ${configured_flow_body}
428 Log ${updating_flow_body}
429 ${xml} Parse Xml <input xmlns="urn:opendaylight:flow:service"></input>
431 ${origflow}= Parse Xml ${configured_flow_body}
432 ${updflow}= Parse Xml ${updating_flow_body}
433 Remove Element ${origflow} id clear_tail=True
434 Remove Element ${updflow} id clear_tail=True
435 Remove Element Attribute ${origflow} xmlns
436 Remove Element Attribute ${updflow} xmlns
437 Set Element Tag ${origflow} original-flow
438 Set Element Tag ${updflow} updated-flow
439 Add Element ${xml} ${origflow}
440 Add Element ${xml} ${updflow}
441 Add Element ${xml} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
442 ${nodeelm}= Get Element ${xml} node
443 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
445 ${strxml}= Element To String ${xml}
446 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:update-flow data=${strxml}
448 Should Be Equal As Strings ${resp.status_code} 200
450 Update Flow Via Restconf
451 [Arguments] ${node_id} ${table_id} ${flow_id} ${flow_body}
452 [Documentation] Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
454 ${resp}= RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} data=${flow_body}
456 ${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.
457 Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}
460 [Arguments] ${node_id} ${xmlroot}
461 [Documentation] Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
462 ... Create Flow Variables For Suite From XML File keyword from this library.
463 ${req}= Copy Element ${xmlroot}
464 Remove Element ${req} id clear_tail=True
465 Set Element Tag ${req} input
466 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
467 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
468 ${nodeelm}= Get Element ${req} node
469 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
471 ${strxml}= Element To String ${req}
472 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:remove-flow data=${strxml}
474 Should Be Equal As Strings ${resp.status_code} 200
476 Delete Flow Via Restconf
477 [Arguments] ${node_id} ${table_id} ${flow_id}
478 [Documentation] Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
479 ${resp}= RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
481 ${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.
482 Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}