CPS-455
-
Getting issue details...
STATUS
Purpose of spike
The purpose of this spike is to investigate how fields and depth can be implemented and used in conjunction with Restconf to gather attributes from xNFs and be able to determine the depth of information retrieved.
RESTConf defines 'fields' and 'depth' parameters to control the output of a get or query request.
See https://tools.ietf.org/id/draft-ietf-netconf-restconf-07.xml and https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.3
module turing-machine {
namespace "http://example.net/turing-machine";
prefix "tm";
description
"Data model for the Turing Machine.";
revision 2013-12-27 {
description
"Initial revision.";
}
/* Typedefs */
typedef tape-symbol {
type string {
length "0..1";
}
description
"Type of symbols appearing in tape cells.
A blank is represented as an empty string where necessary.";
}
typedef cell-index {
type int64;
description
"Type for indexing tape cells.";
}
typedef state-index {
type uint16;
description
"Type for indexing states of the control unit.";
}
typedef head-dir {
type enumeration {
enum left;
enum right;
}
default "right";
description
"Possible directions for moving the read/write head, one cell
to the left or right (default).";
}
/* Groupings */
grouping tape-cells {
description
"The tape of the Turing Machine is represented as a sparse
array.";
list cell {
key "coord";
description
"List of non-blank cells.";
leaf coord {
type cell-index;
description
"Coordinate (index) of the tape cell.";
}
leaf symbol {
type tape-symbol {
length "1";
}
description
"Symbol appearing in the tape cell.
Blank (empty string) is not allowed here because the
'cell' list only contains non-blank cells.";
}
}
}
/* State data and Configuration */
container turing-machine {
description
"State data and configuration of a Turing Machine.";
leaf state {
type state-index;
config "false";
mandatory "true";
description
"Current state of the control unit.
The initial state is 0.";
}
leaf head-position {
type cell-index;
config "false";
mandatory "true";
description
"Position of tape read/write head.";
}
container tape {
config "false";
description
"The contents of the tape.";
uses tape-cells;
}
container transition-function {
description
"The Turing Machine is configured by specifying the
transition function.";
list delta {
key "label";
unique "input/state input/symbol";
description
"The list of transition rules.";
leaf label {
type string;
description
"An arbitrary label of the transition rule.";
}
container input {
description
"Input parameters (arguments) of the transition rule.";
leaf state {
type state-index;
mandatory "true";
description
"Current state of the control unit.";
}
leaf symbol {
type tape-symbol;
mandatory "true";
description
"Symbol read from the tape cell.";
}
}
container output {
description
"Output values of the transition rule.";
leaf state {
type state-index;
description
"New state of the control unit. If this leaf is not
present, the state doesn't change.";
}
leaf symbol {
type tape-symbol;
description
"Symbol to be written to the tape cell. If this leaf is
not present, the symbol doesn't change.";
}
leaf head-move {
type head-dir;
description
"Move the head one cell to the left or right";
}
}
}
}
}
/* RPCs */
rpc initialize {
description
"Initialize the Turing Machine as follows:
1. Put the control unit into the initial state (0).
2. Move the read/write head to the tape cell with coordinate
zero.
3. Write the string from the 'tape-content' input parameter to
the tape, character by character, starting at cell 0. The
tape is othewise empty.";
input {
leaf tape-content {
type string;
default "";
description
"The string with which the tape shall be initialized. The
leftmost symbol will be at tape coordinate 0.";
}
}
}
rpc run {
description
"Start the Turing Machine operation.";
}
rpc run-until {
description
"Start the Turing Machine operation and let it run until it is halted
or ALL the defined breakpoint conditions are satisfied.";
input {
leaf state {
type state-index;
description
"What state the control unit has to be at for the execution to be paused.";
}
leaf head-position {
type cell-index;
description
"Position of tape read/write head for which the breakpoint applies.";
}
container tape {
description
"What content the tape has to have for the breakpoint to apply.";
uses tape-cells;
}
}
output {
leaf step-count {
type uint64;
description
"The number of steps executed since the last 'run-until' call.";
}
leaf halted {
type boolean;
description
"'True' if the Turing machine is halted, 'false' if it is only paused.";
}
}
}
/* Notifications */
notification halted {
description
"The Turing Machine has halted. This means that there is no
transition rule for the current state and tape symbol.";
leaf state {
type state-index;
mandatory "true";
description
"The state of the control unit in which the machine has
halted.";
}
}
notification paused {
description
"The Turing machine has reached a breakpoint and was paused.";
leaf state {
type state-index;
mandatory "true";
description
"State of the control unit in which the machine was paused.";
}
leaf head-position {
type cell-index;
mandatory "true";
description
"Position of tape read/write head when the machine was paused.";
}
container tape {
description
"Content of the tape when the machine was paused.";
uses tape-cells;
}
}
}
{
"turing-machine": {
"transition-function": {
"delta": [
{
"label": "separator",
"input": {
"state": 0,
"symbol": "0"
},
"output": {
"state": 1,
"symbol": "1"
}
},
{
"label": "write separator",
"input": {
"state": 2,
"symbol": "1"
},
"output": {
"state": 3,
"symbol": "0",
"head-move": "left"
}
},
{
"label": "right summand",
"input": {
"state": 1,
"symbol": "1"
}
},
{
"label": "final step",
"input": {
"state": 3,
"symbol": ""
},
"output": {
"state": 4
}
},
{
"label": "go home",
"input": {
"state": 3,
"symbol": "1"
},
"output": {
"head-move": "left"
}
},
{
"label": "right end",
"input": {
"state": 1,
"symbol": ""
},
"output": {
"state": 2,
"head-move": "left"
}
},
{
"label": "left summand",
"input": {
"state": 0,
"symbol": "1"
}
}
]
}
}
}
The capabilities of both parameters as defined by RESTConf
Fields
The "fields" query parameter is used to optionally identify data nodes within the target resource to be retrieved in a GET method. The client can use this parameter to retrieve a subset of all nodes in a resource.
- ";" is used to select multiple nodes. For example, to retrieve only the "genre" and "year" of an album, use: "fields=genre;year".
- Parentheses are used to specify sub-selectors of a node. For example, to retrieve only the "label" and "catalogue‑number" of an album, use: "fields=admin(label;catalogue‑number)".
- "/" is used in a path to retrieve a child node of a node. For example, to retrieve only the "label" of an album, use: "fields=admin/label".
- This parameter is only allowed for GET methods on api, datastore, and data resources. A 400 Bad Request error is returned if used for other methods or resource types.
Fields example
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?fields=delta/output/state
Depth
The "depth" parameter is used to specify the number of nest levels returned in a response for a GET method. The first nest-level consists of the requested data node itself. Any child nodes which are contained within a parent node have a depth value that is 1 greater than its parent.
- The value of the "depth" parameter is either an integer between 1 and 65535, or the string "unbounded". "unbounded" is the default.
- This parameter is only allowed for GET methods on API, datastore, and data resources. A 400 Bad Request error is returned if it used for other methods or resource types.
- By default, the server will include all sub-resources within a retrieved resource, which have the same resource type as the requested resource. Only one level of sub-resources with a different media type than the target resource will be returned.
Depth Example
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?depth=1
The support/limitations of both parameters as implemented by the 'rests' ODL module interface (SDN-C)
The "rests" odl interface supports fields and depth parameters
Assumptions
Assumption | Notes |
---|
rests bundle is enable by default |
|
node has been mounted |
|
rests Interface Fields Examples
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?fields=delta/output/state
{
"turing-machine:turing-machine": {
"transition-function": {
"delta": [
{
"output": {
"state": 1
}
},
{
"output": {
"state": 3
}
},
{},
{
"output": {
"state": 4
}
},
{},
{
"output": {
"state": 2
}
},
{}
]
}
}
}
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?fields=delta/output/state;symbolor
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine?fields=transition-function(delta/output/state;symbol)
{
"turing-machine:transition-function": {
"delta": [
{
"output": {
"state": 1,
"symbol": "1"
}
},
{
"output": {
"state": 3,
"symbol": "0"
}
},
{},
{
"output": {
"state": 4
}
},
{},
{
"output": {
"state": 2
}
},
{}
]
}
}
Get specific fields for specific delta
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function/delta=separator/input?fields=state
{
"turing-machine:input": {
"state": 0
}
}
rests Interface Depth Examples
If the "fields" parameter is used to select descendant data nodes, then these nodes and all of their ancestor nodes have a "depth" value of "1".
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?depth=1
Note: same response for depth=2
http://localhost:8282/restsdata/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?depth=3
{
"transition-function": {
"delta": [
{},
{},
{},
{},
{},
{},
{}
]
}
}
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?depth=4
{
"transition-function": {
"delta": [
{
"label": "separator"
},
{
"label": "write separator"
},
{
"label": "right summand"
},
{
"label": "final step"
},
{
"label": "go home"
},
{
"label": "right end"
},
{
"label": "left summand"
}
]
}
}
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?depth=5
{
"transition-function": {
"delta": [
{
"label": "separator",
"input": {
"state": 0,
"symbol": "0"
},
"output": {
"state": 1,
"symbol": "1"
}
},
{
"label": "write separator",
"input": {
"state": 2,
"symbol": "1"
},
"output": {
"state": 3,
"symbol": "0",
"head-move": "left"
}
},
{
"label": "right summand",
"input": {
"state": 1,
"symbol": "1"
}
},
{
"label": "final step",
"input": {
"state": 3,
"symbol": ""
},
"output": {
"state": 4
}
},
{
"label": "go home",
"input": {
"state": 3,
"symbol": "1"
},
"output": {
"head-move": "left"
}
},
{
"label": "right end",
"input": {
"state": 1,
"symbol": ""
},
"output": {
"state": 2,
"head-move": "left"
}
},
{
"label": "left summand",
"input": {
"state": 0,
"symbol": "1"
}
}
]
}
}
Note: Depth of 0 will result in a 400 (Bad Request)
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?depth=0
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Error 400 Bad Request</title>
</head>
<body>
<h2>HTTP ERROR 400</h2>
<p>Problem accessing
/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function.
Reason:
<pre> Bad Request</pre>
</p>
</body>
</html>
The feasibility/cost of NCMP 'translating' a fields-option without module information into a RESTConf compatible fields value. High level user story view of cost.
Fields that come in via NCMP will need to be translated into Restconf compatible fields.
Can we delegate to rests interface and supply fields "as is"
The feasibility/cost of support a 'depth' parameter for CPS cached data and/or ONAP DMI Plugin
High level user story view of cost
Will need to determine what is meant by cps cached data
Interaction Between Fields & Depth Parameters
Note: Depth can be any value .> 0. However, all details above field in question will be added to output
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?fields=delta/output/state&depth=1
{
"transition-function": {
"delta": [
{
"output": {
"state": 1
}
},
{
"output": {
"state": 3
}
},
{},
{
"output": {
"state": 4
}
},
{},
{
"output": {
"state": 2
}
},
{}
]
}
}
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?fields=delta/output/state&depth=2
Note: field take precedence so adding depth=2 is the same as depth=1
{
"transition-function": {
"delta": [
{
"output": {
"state": 1
}
},
{
"output": {
"state": 3
}
},
{},
{
"output": {
"state": 4
}
},
{},
{
"output": {
"state": 2
}
},
{}
]
}
}
Can also work with multiple fields as above
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine:turing-machine/transition-function?fields=delta/output/state;symbol&depth=2
{
"transition-function": {
"delta": [
{
"output": {
"state": 1,
"symbol": "1"
}
},
{
"output": {
"state": 3,
"symbol": "0"
}
},
{},
{
"output": {
"state": 4
}
},
{},
{
"output": {
"state": 2
}
},
{}
]
}
}
Fields with module example
http://localhost:8282/rests/data/network-topology:network-topology/topology=topology-netconf/node=PNFDemo/yang-ext:mount/turing-machine?depth=1&fields=turing-machine:transition-function/turing-machine:delta/turing-machine:output(state)
{
"turing-machine": {
"transition-function": {
"delta": [
{
"output": {
"state": 1
}
},
{
"output": {
"state": 3
}
},
{},
{
"output": {
"state": 4
}
},
{},
{
"output": {
"state": 2
}
},
{}
]
}
}
}
Findings from Demo
{
"turing-machine:delta": [
{
"label": "separator",
"input": {
"state": 0,
"symbol": "0"
},
"output": {
"state": 1,
"symbol": "1"
}
}
]
}
{
"turing-machine:input": {
"state": 0,
"symbol": "0"
}
}
{
"turing-machine:input": {
"state": 0
}
}
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Error 404 Not Found</title>
</head>
<body>
<h2>HTTP ERROR 404</h2>
<p>Problem accessing /restconf/data. Reason:
<pre> Not Found</pre>
</p>
</body>
</html>
Video of Demo
zoom_0.mp4
Questions
Question | Answer |
---|
When field function is used to list attributes in child will the parent still be part of output? | Yes if we do not specicially use delta=separator/input?fields=state |
|
|
Setting up local netconf-pnp-simulator & SDNC environment
- Run docker load -i image.tar to unpack netconf docker image v2.8.6
- Unzip certs.tar to same folder as docker-compose.yml (SDNC docker)
- Unpack sim.zip
- Run docker-compose up -d
- Run sim/docker-compose -f docker-compose-sim.yml up -d (netconf-pnp-simulator docker)
- To access local SDNC/ODL use - http://localhost:8282/apidoc/explorer/index.html
- Credentials : - admin / Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U