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".
7 Library OperatingSystem
8 Library RequestsLibrary
13 Library ScaleClient.py
14 Library XmlComparator.py
15 Resource CompareStream.robot
16 Resource TemplatedRequests.robot
17 Resource ../variables/openflowplugin/Variables.robot
18 Variables ../variables/Variables.py
22 Check No Switches In Inventory
23 [Documentation] Check no switch is in inventory
24 [Arguments] ${switches}
25 ${resp}= RequestsLibrary.GET On Session
27 ... url=${RFC8040_OPERATIONAL_NODES_API}
28 ... expected_status=200
30 FOR ${switch} IN RANGE 1 ${switches+1}
31 Should Not Contain ${resp.text} "openflow:${switch}"
34 Check No Switches In Topology
35 [Documentation] Check no switch is in topology
36 [Arguments] ${switches}
37 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_TOPO_API} expected_status=200
39 FOR ${switch} IN RANGE 1 ${switches+1}
40 Should Not Contain ${resp.text} openflow:${switch}
43 Check Switches In Inventory
44 [Documentation] Check all switches and stats in operational inventory
45 [Arguments] ${switches}
46 FOR ${switch} IN RANGE 1 ${switches+1}
47 ${resp}= RequestsLibrary.GET On Session
49 ... url=${RFC8040_NODES_API}/node=openflow%3A${switch}
50 ... expected_status=200
52 Should Contain ${resp.text} flow-capable-node-connector-statistics
53 Should Contain ${resp.text} flow-table-statistics
56 Check Switches In Topology
57 [Documentation] Check switches are in the topology.
58 [Arguments] ${switches}
59 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_TOPO_API} expected_status=200
61 ${count}= Get Count ${resp.text} "node-id":"openflow:
62 BuiltIn.Should Be Equal As Numbers ${count} ${switches}
65 [Documentation] Check number of links in the topolgy.
67 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_TOPO_API} expected_status=200
69 ${count}= Get Count ${resp.text} "link-id":"openflow:
70 Should Be Equal As Integers ${count} ${links}
73 [Documentation] Check Linear topology.
74 [Arguments] ${switches}
75 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_TOPO_API} expected_status=200
77 FOR ${switch} IN RANGE 1 ${switches+1}
78 Should Contain ${resp.text} "node-id":"openflow:${switch}"
79 Should Contain ${resp.text} "tp-id":"openflow:${switch}:1"
80 Should Contain ${resp.text} "tp-id":"openflow:${switch}:2"
81 Should Contain ${resp.text} "source-tp":"openflow:${switch}:2"
82 Should Contain ${resp.text} "dest-tp":"openflow:${switch}:2"
83 ${edge}= Evaluate ${switch}==1 or ${switch}==${switches}
85 Should Contain ${resp.text} "tp-id":"openflow:${switch}:3"
88 Should Contain ${resp.text} "source-tp":"openflow:${switch}:3"
91 Should Contain ${resp.text} "dest-tp":"openflow:${switch}:3"
95 Check Flows Operational Datastore
96 [Documentation] Check if number of Operational Flows on member of given index is equal to ${flow_count}.
97 [Arguments] ${flow_count} ${controller_ip}=${ODL_SYSTEM_IP}
98 ${sw} ${reported_flow} ${found_flow}= ScaleClient.Flow Stats Collected controller=${controller_ip}
99 Should_Be_Equal_As_Numbers ${flow_count} ${found_flow}
101 Check Number Of Flows
102 [Documentation] Check number of flows in the inventory.
104 ${resp}= RequestsLibrary.GET On Session
106 ... url=${RFC8040_OPERATIONAL_NODES_API}
107 ... expected_status=200
109 ${count}= Get Count ${resp.text} "priority"
110 Should Be Equal As Integers ${count} ${flows}
112 Check Number Of Groups
113 [Documentation] Check number of groups in the inventory.
114 [Arguments] ${groups}
115 ${resp}= RequestsLibrary.GET On Session
117 ... url=${RFC8040_OPERATIONAL_NODES_API}
118 ... expected_status=200
120 ${group_count}= Get Count ${resp.text} "group-type"
121 Should Be Equal As Integers ${group_count} ${groups}
123 Check Flow Stats Are Available
124 [Documentation] A GET on the /node=${node_id} inventory API is made and flow stats string is checked for existence.
125 [Arguments] ${node_id} ${flows}
126 ${resp}= RequestsLibrary.GET On Session
128 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:table=2
129 ... expected_status=200
131 Should Contain X Times ${resp.text} priority ${flows}
133 Check Number Of Hosts
134 [Documentation] Check number of hosts in topology
136 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_TOPO_API} expected_status=200
138 ${count}= Get Count ${resp.text} "node-id":"host:
139 Should Be Equal As Integers ${count} ${hosts}
142 [Documentation] Check if all hosts are deleted from inventory
143 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_TOPO_API} expected_status=200
144 Should Not Contain ${resp.text} "node-id":"host:
147 [Documentation] Add table miss flows to switches.
148 [Arguments] ${switches}
149 ${switches}= Convert To Integer ${switches}
150 ${data}= OperatingSystem.Get File ${CURDIR}/../variables/openflowplugin/table_miss_flow.json
151 FOR ${switch} IN RANGE 1 ${switches+1}
152 TemplatedRequests.Put As Json To Uri
153 ... ${RFC8040_NODES_API}/node=openflow%3A${switch}/flow-node-inventory:table=0/flow=default
158 Check Table Miss Flows
159 [Documentation] Check table miss flows in switches.
160 [Arguments] ${switches}
161 ${switches}= Convert To Integer ${switches}
162 FOR ${switch} IN RANGE 1 ${switches+1}
163 TemplatedRequests.Get As Json From Uri
164 ... ${RFC8040_NODES_API}/node=openflow%3A${switch}/flow-node-inventory:table=0/flow=default
168 Create Inventory Flow
169 [Documentation] Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
170 ... the basic flow elements that can be given to flow:inventory
171 ${flow}= Make Inventory Flow
175 [Documentation] Used for creating an object that will use an XML format that
176 ... can be given to flow:service.
177 ${flow}= Make Service Flow
180 Set "${flow}" "${property}" With "${property_val}"
181 [Documentation] Embedded variables to make higher level keywords more readable.
182 ... There are some cases where the python attribute uses an underscore,
183 ... but a hyphen needs to be used. This seems inconsistent, and may need
184 ... to be looked at from the openflow plugin perspective.
186 ... At this point, this library will remove the element ${property} from the
187 ... xml representation of the flow and reset with the given value. \ It's not
188 ... possible, yet, to have multiple elements with the same name. \ That will
189 ... likely be needed in the future.
190 IF "table_id" != "${property}" and "cookie_mask" != "${property}"
191 ${property}= Replace String ${property} _ -
193 ${property}= Set Variable ${property}
195 Remove Flow XML Element ${flow} ${property}
196 Add Flow XML Element ${flow} ${property} ${property_val}
197 Set Flow Field ${flow} ${property} ${property_val}
201 [Documentation] Will remove the instruction element first, then add the proper xml structure
202 ... to implement the action as given in the arguments
203 [Arguments] ${flow} ${instruction_order} ${action_order} ${action} ${action_val}=${EMPTY}
204 ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
205 Remove Flow XML Element ${flow} instruction
206 Add Flow XML Element ${flow} instruction ${EMPTY} instructions
207 Add Flow XML Element ${flow} order ${instruction_order} instructions/instruction
208 Add Flow XML Element ${flow} apply-actions ${EMPTY} instructions/instruction
209 Add Flow XML Element ${flow} action ${EMPTY} instructions/instruction/apply-actions
210 Add Flow XML Element ${flow} order ${action_order} instructions/instruction/apply-actions/action
211 Add Flow XML Element ${flow} ${action} ${action_val} instructions/instruction/apply-actions/action
214 Set Flow Output Action
215 [Arguments] ${flow} ${instruction_order} ${action_order} ${output_port}
216 Set Flow Action ${flow} ${instruction_order} ${action_order} output-action
219 ... output-node-connector
221 ... instructions/instruction/apply-actions/action/output-action
224 Set Flow Ethernet Match
225 [Documentation] Specific keyword for adding an ethernet match rules where the elements are given
226 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
227 ... existing ethernet-match elements from the flow before adding
228 [Arguments] ${flow} ${match_value_dict}
229 Clear Flow Matches ${flow} match/ethernet-match
230 Add Flow XML Element ${flow} ethernet-match ${EMPTY} match
231 ${type}= Get From Dictionary ${match_value_dict} type
232 Add Flow XML Element ${flow} ethernet-type ${EMPTY} match/ethernet-match
233 Add Flow XML Element ${flow} type ${type} match/ethernet-match/ethernet-type
234 ${src}= Get From Dictionary ${match_value_dict} source
235 Add Flow XML Element ${flow} ethernet-source ${EMPTY} match/ethernet-match
236 Add Flow XML Element ${flow} address ${src} match/ethernet-match/ethernet-source
237 ${dst}= Get From Dictionary ${match_value_dict} destination
238 Add Flow XML Element ${flow} ethernet-destination ${EMPTY} match/ethernet-match
239 Add Flow XML Element ${flow} address ${dst} match/ethernet-match/ethernet-destination
243 [Documentation] Specific keyword for adding an ipv4 match rules where the elements are given
244 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
245 ... existing ipv4 match elements from the flow before adding
246 [Arguments] ${flow} ${match_value_dict}
247 Clear Flow Matches ${flow} match/ipv4-source
248 Clear Flow Matches ${flow} match/ipv4-destination
249 ${src}= Get From Dictionary ${match_value_dict} source
250 Add Flow XML Element ${flow} ipv4-source ${src} match
251 ${dst}= Get From Dictionary ${match_value_dict} destination
252 Add Flow XML Element ${flow} ipv4-destination ${dst} match
256 [Documentation] Will clean out any existing flow actions in the given ${flow} object
258 Remove Flow XML Element ${flow} instructions/instruction
262 [Documentation] Will clean out any existing flow matches in the given ${flow} object
263 [Arguments] ${flow} ${match_element}
264 Remove Flow XML Element ${flow} match/${match_element}
267 Set Flow XML Element Attribute
268 [Documentation] Will set the given id/value pair to the given to the element provided
269 ... and make the proper changes to the ${flow} object also provided.
270 [Arguments] ${flow} ${element} ${id} ${value}
271 ${flow_xml}= Parse XML ${flow.xml}
272 Set Element Attribute ${flow_xml} ${id} ${value} xpath=${element}
273 ${xml_string}= Element To String ${flow_xml}
274 Set Flow Field ${flow} xml ${xml_string}
279 [Documentation] Will modify the current xml representation of the ${flow} object to contain
280 ... the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
281 ... passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
282 ... are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
283 ... you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
284 ... location in the parameter list
285 [Arguments] ${flow} ${element} ${element_val}=${EMPTY} ${xpath}=.
286 ${flow_xml}= Parse XML ${flow.xml}
287 Add Element ${flow_xml} <${element}>${element_val}</${element}> xpath=${xpath}
288 ${xml_string}= Element To String ${flow_xml}
289 Set Flow Field ${flow} xml ${xml_string}
293 Remove Flow XML Element
294 [Documentation] Removes the element at the given ${element_xpath} within the given ${flow}
295 ... object. The ${flow} object's xml representation will be updated to reflect this removal.
296 [Arguments] ${flow} ${element_xpath}
297 ${flow_xml}= Parse XML ${flow.xml}
298 Run Keyword And Ignore Error Remove Elements ${flow_xml} xpath=${element_xpath}
299 ${xml_string}= Element To String ${flow_xml}
300 Set Flow Field ${flow} xml ${xml_string}
303 Add Group To Controller And Verify
304 [Documentation] Push group through REST-API and verify in data-store
305 [Arguments] ${group_body} ${node_id} ${group_id}
306 ${resp}= RequestsLibrary.PUT On Session
308 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:group=${group_id}
309 ... headers=${HEADERS_XML}
310 ... data=${group_body}
312 ${resp}= RequestsLibrary.GET On Session
314 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:group=${group_id}?content=config
315 ... headers=${ACCEPT_XML}
316 ... expected_status=200
318 Compare Xml ${group_body} ${resp.text}
320 Add Flow To Controller And Verify
321 [Documentation] Push flow through REST-API and verify in data-store
322 [Arguments] ${flow_body} ${node_id} ${table_id} ${flow_id}
323 ${resp}= RequestsLibrary.PUT On Session
325 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:table=${table_id}/flow=${flow_id}
326 ... headers=${HEADERS_XML}
327 ... data=${flow_body}
329 ${resp}= RequestsLibrary.GET On Session
331 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:table=${table_id}/flow=${flow_id}?content=config
332 ... headers=${ACCEPT_XML}
333 ... expected_status=200
335 Compare Xml ${flow_body} ${resp.text}
337 Verify Flow On Mininet Switch
338 [Documentation] Checking flow on switch
339 [Arguments] ${flow_elements}
341 Write dpctl dump-flows -O OpenFlow13
342 ${switchoutput}= Read Until >
343 FOR ${flowElement} IN @{flow_elements}
344 Should Contain ${switchoutput} ${flowElement}
347 Remove Group From Controller And Verify
348 [Documentation] Remove group and verify
349 [Arguments] ${node_id} ${group_id}
350 ${resp}= RequestsLibrary.DELETE On Session
352 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:group=${group_id}
353 ... expected_status=204
355 ${resp}= RequestsLibrary.Get On Session
357 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:group=${group_id}?content=config
358 ... expected_status=anything
359 IF ${resp.status_code} == 404 or ${resp.status_code} == 409 RETURN
360 Builtin.Log ${resp.text}
361 Builtin.Fail The request failed with code ${resp.status_code}
363 Remove Flow From Controller And Verify
364 [Documentation] Remove flow and verify
365 [Arguments] ${node_id} ${table_id} ${flow_id}
366 ${resp}= RequestsLibrary.DELETE On Session
368 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:table=${table_id}/flow=${flow_id}
369 ... expected_status=204
371 ${resp}= RequestsLibrary.Get On Session
373 ... url=${RFC8040_NODES_API}/node=${node_id}/flow-node-inventory:table=${table_id}/flow=${flow_id}?content=config
374 ... expected_status=anything
375 IF ${resp.status_code} == 404 or ${resp.status_code} == 409 RETURN
376 Builtin.Log ${resp.text}
377 Builtin.Fail The request failed with code ${resp.status_code}
379 Verify Flow Does Not Exist On Mininet Switch
380 [Documentation] Checking flow on switch is removed
381 [Arguments] ${flow_elements}
383 Write dpctl dump-flows -O OpenFlow13
384 ${switchoutput}= Read Until >
385 FOR ${flowElement} IN @{flow_elements}
386 Should Not Contain ${switchoutput} ${flowElement}
390 [Documentation] Removes any flows considered "default". one such flow is
391 ... to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
392 ... If/When others are implemented this keyword can be updated to include those.
393 [Arguments] ${node_id}
394 ${flow}= Make Service Flow
395 Set "${flow}" "priority" With "0"
396 Set "${flow}" "flow-table" With "0"
397 Add Flow XML Element ${flow} node /inv:nodes/inv:node[inv:id="${node_id}"]
398 Set Flow XML Element Attribute ${flow} node xmlns:inv urn:opendaylight:inventory
399 Log Flow XML is ${flow.xml}
400 write dpctl dump-flows -O OpenFlow13
401 ${switchoutput}= Read Until >
402 ${headers}= Create Dictionary Content-Type=application/yang-data+xml
403 ${resp}= RequestsLibrary.POST On Session
405 ... url=rests/operations/sal-flow:remove-flow
407 ... headers=${headers}
408 ... expected_status=200
410 ${resp}= RequestsLibrary.GET On Session session url=${RFC8040_OPERATIONAL_NODES_API}
412 Should Not Contain ${resp.text} "output-node-connector": "CONTROLLER",
413 ${strings_to_check_for}= Create List CONTROLLER
414 Verify Flow Does Not Exist On Mininet Switch ${strings_to_check_for}
416 Create Flow Variables For Suite From XML File
417 [Documentation] Given the flow XML ${file}, it will create several suite wide variables
419 ${data}= OperatingSystem.Get File ${file}
420 ${xmlroot}= Parse Xml ${file}
421 ${table_id}= Get Element Text ${xmlroot} table_id
422 ${flow_id}= Get Element Text ${xmlroot} id
423 ${flow_priority}= Get Element Text ${xmlroot} priority
424 ${upddata}= Get Data For Flow Put Update ${data}
425 Set Suite Variable ${table_id}
426 Set Suite Variable ${flow_id}
427 Set Suite Variable ${flow_priority}
428 Set Suite Variable ${data}
429 Set Suite Variable ${upddata}
430 Set Suite Variable ${xmlroot}
432 Check Datastore Presence
433 [Documentation] Checks if flow is properly existing or not existing in the config and operational
434 ... datastores, based on the variables ${reqconfpres} and ${reqoperpres}
435 [Arguments] ${fname} ${reqconfpres} ${reqoperpres} ${upd} ${check_id}=${False}
436 Create Flow Variables For Suite From XML File ${XmlsDir}/${fname}
437 # Note: ${upddata} and ${data} are suite variables set by the keyword above.
438 ${det}= Set Variable If ${upd}==${True} ${upddata} ${data}
440 Check Config Flow ${reqconfpres} ${det}
441 Check Operational Flow ${reqoperpres} ${det} ${check_id}
443 Flow Presence In Config Store
444 [Documentation] Checks the config store for given flow. Returns True if present, otherwise returns False
445 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
446 [Arguments] ${expvalue}
447 ${headers}= Create Dictionary Accept=application/xml
448 ${resp}= RequestsLibrary.Get On Session
450 ... url=${RFC8040_NODES_API}/node=openflow%3A${switch_idx}/flow-node-inventory:table=${table_id}/flow=${flow_id}?content=config
451 ... headers=${headers}
452 ... expected_status=anything
455 IF ${resp.status_code}!=200 RETURN ${False} ${EMPTY}
456 ${pres} ${msg}= Is Flow Configured ${expvalue} ${resp.text}
457 IF '''${msg}'''!='${EMPTY}' Log ${msg}
458 RETURN ${pres} ${msg}
460 Flow Presence In Operational Store
461 [Documentation] Checks the operational store for given flow. Returns True if present, otherwise returns False
462 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
463 [Arguments] ${expvalue} ${check_id}=${False}
464 ${headers}= Create Dictionary Accept=application/xml
465 ${resp}= RequestsLibrary.Get On Session
467 ... url=${RFC8040_NODES_API}/node=openflow%3A${switch_idx}/flow-node-inventory:table=${table_id}
468 ... headers=${headers}
469 ... expected_status=anything
472 IF ${resp.status_code}!=200 RETURN ${False} ${EMPTY}
473 ${pres} ${msg}= Is Flow Operational2 ${expvalue} ${resp.text} ${check_id}
474 IF '''${msg}'''!='${EMPTY}' Log ${msg}
475 RETURN ${pres} ${msg}
477 Get Presence Failure Message
478 [Documentation] Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
479 [Arguments] ${ds} ${expected} ${presence} ${diffmsg}
480 IF '''${diffmsg}'''!='${EMPTY}'
481 RETURN Flow found in ${ds} data store but: ${diffmsg}
483 ${msgf}= Set Variable If
484 ... ${expected}==${True}
485 ... The flow is expected in ${ds} data store, but
486 ... The flow is not expected in ${ds} data store, but
487 ${msgp}= Set Variable If ${presence}==${True} it is present. it is not present.
488 RETURN ${msgf} ${msgp}
491 [Documentation] Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
492 ... to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
493 [Arguments] ${expected} ${expvalue}
494 ${presence_flow} ${msg}= Flow Presence In Config Store ${expvalue}
495 ${msgf}= Get Presence Failure Message config ${expected} ${presence_flow} ${msg}
496 Should Be Equal ${expected} ${presence_flow} msg=${msgf}
498 Check Operational Flow
499 [Documentation] Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
500 ... to verify that the ${expvalue} flow is or is not found in the operational store, depending on whether or not it was ${expected}
501 [Arguments] ${expected} ${expvalue} ${check_id}=${False}
502 ${presence_table} ${msg}= Flow Presence In Operational Store ${expvalue} ${check_id}
503 ${msgf}= Get Presence Failure Message operational ${expected} ${presence_table} ${msg}
504 Should Be Equal ${expected} ${presence_table} msg=${msgf}
507 [Documentation] Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
508 ... ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
509 ... keyword from this library.
510 [Arguments] ${node_id} ${xmlroot}
511 ${req}= Copy Element ${xmlroot}
512 Remove Element ${req} id clear_tail=True
513 Set Element Tag ${req} input
514 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
515 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
516 ${nodeelm}= Get Element ${req} node
517 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
519 ${strxml}= Element To String ${req}
520 ${resp}= RequestsLibrary.POST On Session
522 ... url=/rests/operations/sal-flow:add-flow
524 ... expected_status=204
527 Add Flow Via Restconf
528 [Documentation] Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
529 [Arguments] ${node_id} ${table_id} ${flow_body}
531 ${resp}= RequestsLibrary.POST On Session
533 ... url=${RFC8040_NODES_API}/node=openflow%3A${node_id}/flow-node-inventory:table=${table_id}
534 ... data=${flow_body}
535 ... expected_status=201
539 [Documentation] Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
540 ... Create Flow Variables For Suite From XML File keyword from this library.
541 [Arguments] ${node_id} ${configured_flow_body} ${updating_flow_body}
542 Log ${configured_flow_body}
543 Log ${updating_flow_body}
544 ${xml}= Parse Xml <input xmlns="urn:opendaylight:flow:service"></input>
546 ${origflow}= Parse Xml ${configured_flow_body}
547 ${updflow}= Parse Xml ${updating_flow_body}
548 Remove Element ${origflow} id clear_tail=True
549 Remove Element ${updflow} id clear_tail=True
550 Remove Element Attribute ${origflow} xmlns
551 Remove Element Attribute ${updflow} xmlns
552 Set Element Tag ${origflow} original-flow
553 Set Element Tag ${updflow} updated-flow
554 Add Element ${xml} ${origflow}
555 Add Element ${xml} ${updflow}
556 Add Element ${xml} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
557 ${nodeelm}= Get Element ${xml} node
558 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
560 ${strxml}= Element To String ${xml}
561 ${resp}= RequestsLibrary.POST On Session
563 ... url=/rests/operations/sal-flow:update-flow
565 ... expected_status=204
568 Update Flow Via Restconf
569 [Documentation] Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
570 [Arguments] ${node_id} ${table_id} ${flow_id} ${flow_body}
572 ${resp}= RequestsLibrary.PUT On Session
574 ... url=${RFC8040_NODES_API}/node=openflow%3A${node_id}/flow-node-inventory:table=${table_id}/flow=${flow_id}
575 ... data=${flow_body}
576 ... expected_status=204
580 [Documentation] Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
581 ... Create Flow Variables For Suite From XML File keyword from this library.
582 [Arguments] ${node_id} ${xmlroot}
583 ${req}= Copy Element ${xmlroot}
584 Remove Element ${req} id clear_tail=True
585 Set Element Tag ${req} input
586 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
587 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
588 ${nodeelm}= Get Element ${req} node
589 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
591 ${strxml}= Element To String ${req}
592 ${resp}= RequestsLibrary.POST On Session
594 ... url=/rests/operations/sal-flow:remove-flow
596 ... expected_status=204
599 Delete Flow Via Restconf
600 [Documentation] Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
601 [Arguments] ${node_id} ${table_id} ${flow_id}
602 ${resp}= RequestsLibrary.DELETE On Session
604 ... url=${RFC8040_NODES_API}/node=openflow%3A${node_id}/flow-node-inventory:table=${table_id}/flow=${flow_id}
605 ... expected_status=204
609 [Documentation] This verifies specific flow-id for particular table-id matching from the flow element
610 [Arguments] ${dpnid} ${table_id} ${flow_element}
611 ${resp}= RequestsLibrary.GET On Session
613 ... url=${RFC8040_NODES_API}/node=openflow%3A${dpnid}/flow-node-inventory:table=${table_id}?content=config
614 BuiltIn.Log ${resp.text}
615 @{flow_id}= String.Get Regexp Matches ${resp.text} id\":\"(\\d+${flow_element}) 1