corenova / yang-js

YANG parser and composer
Apache License 2.0
56 stars 18 forks source link

leafref support issues on ietf-network-topology@2017-12-18 #68

Open quantang opened 6 years ago

quantang commented 6 years ago

Hello,

I am trying to make yang-js work with "ietf-network-topology" schema (rfc8345), and noticed the following issues on "leafref" statement:

  1. The "../" in leafref path may not work right with list elements. I guess it take the [index] as part of path. So I need to change the schema file and add some additional "../" to make it pass.
  2. The prefix may not work right. As the "ietf-network-topology" (prefix nt) imports the "ietf-network" (prefix nw), it use "nw:node" to refer the nodes defined in "ietf-network". However, as the whole data is defined as "ietf-network:networks", there is no module name before the "node" element, which makes it failed to find the matching one.
  3. It cannot handle the path expression with "../../../nw:node[nw:node-id=current()/../source-node]/termination-point/tp-id". I guess it has been mentioned in issue-49 as XPATH parsing issue.

So, right now I need to change the path from: path "../../../nw:node[nw:node-id=current()/../dest-node]/termination-point/tp-id"; into: path "../../../../node/nt:termination-point/tp-id"; to get it passed.

Please correct me if I use it in a wrong way.

Here is the "leafref" in the schema file:

      container source {
        description
          "This container holds the logical source of a particular
           link.";
        leaf source-node {
          type leafref {
            path "../../../nw:node/nw:node-id";
            require-instance false;
          }
          description
            "Source node identifier, must be in same topology.";
        }
        leaf source-tp {
          type leafref {
            path "../../../nw:node[nw:node-id=current()/../"+
              "source-node]/termination-point/tp-id";
            require-instance false;
          }
          description
            "Termination point within source node that terminates
             the link.";
        }
      }

Here is the test data that I am using:

{
    "ietf-network:networks": {
        "network": [{
            "network-types": {},
            "network-id": "physical",
            "node": [{
                "node-id": "0000.0001.0000",
                "ietf-network-topology:termination-point": [{
                    "tp-id": "1-0-1"
                }]
            }, {
                "node-id": "0000.0002.0000",
                "ietf-network-topology:termination-point": [{
                    "tp-id": "2-0-1"
                }]
            }],
            "ietf-network-topology:link": [{
                "link-id": "link-1",
                "source": {
                    "source-node": "0000.0001.0000",
                    "source-tp": "1-0-1"
                },
                "destination": {
                    "dest-node": "0000.0002.0000",
                    "dest-tp": "2-0-1"
                }
            }]
        }]
    }
}
sekur commented 6 years ago

Hi Quan,

Please see my comments inline:

On Sun, Aug 5, 2018 at 3:38 PM Quan Tang notifications@github.com wrote:

Hello,

I am trying to make yang-js work with "ietf-network-topology https://raw.githubusercontent.com/YangModels/yang/master/experimental/ietf-extracted-YANG-modules/ietf-network-topology@2017-12-18.yang" schema (rfc8345), and noticed the following issues on "leafref" statement:

  1. The "../" in leafref path may not work right with list elements. I guess it take the [index] as part of path. So I need to change the schema file and add some additional "../" to make it pass.

You are correct, I don’t think I’m handling the relative leafref path expressions correctly when dealing with “list” entity. There is an extra “index object” when I expressed the list entity in JS. I’ll need to fix this...

  1. The prefix may not work right. As the "ietf-network-topology" (prefix nt) imports the "ietf-network https://raw.githubusercontent.com/YangModels/yang/master/experimental/ietf-extracted-YANG-modules/ietf-network@2017-12-18.yang" (prefix nw), it use "nw:node" to refer the nodes defined in "ietf-network". However, as the whole data is defined as "ietf-network:networks", there is no module name before the "node" element, which makes it failed to find the matching one.

I think I follow the issue here but an example will be most helpful.

  1. It cannot handle the path expression with "../../../nw:node[nw:node-id=current()/../source-node]/termination-point/tp-id". I guess it has been mentioned in issue-49 https://github.com/corenova/yang-js/issues/49 as XPATH parsing issue.

Yes, XPATH predicate expression handling is quite limited. I can use some help here - either a reference to a good XPATH parsing JS library or help enhancing the underlying “xparse” library for evaluating predicate expressions.

So, right now I need to change the path from:

path "../../../nw:node[nw:node-id=current()/../dest-node]/termination-point/tp-id"; into: path "../../../../node/nt:termination-point/tp-id"; to get it passed.

Please correct me if I use it in a wrong way.

Here is the "leafref" in the schema file:

  container source {
    description
      "This container holds the logical source of a particular
       link.";
    leaf source-node {
      type leafref {
        path "../../../nw:node/nw:node-id";
        require-instance false;
      }
      description
        "Source node identifier, must be in same topology.";
    }
    leaf source-tp {
      type leafref {
        path "../../../nw:node[nw:node-id=current()/../"+
          "source-node]/termination-point/tp-id";
        require-instance false;
      }
      description
        "Termination point within source node that terminates
         the link.";
    }
  }

Here is the test data that I am using:

{ "ietf-network:networks": { "network": [{ "network-types": {}, "network-id": "physical", "node": [{ "node-id": "0000.0001.0000", "ietf-network-topology:termination-point": [{ "tp-id": "1-0-1" }] }, { "node-id": "0000.0002.0000", "ietf-network-topology:termination-point": [{ "tp-id": "2-0-1" }] }], "ietf-network-topology:link": [{ "link-id": "link-1", "source": { "source-node": "0000.0001.0000", "source-tp": "1-0-1" }, "destination": { "dest-node": "0000.0002.0000", "dest-tp": "2-0-1" } }] }] } }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/corenova/yang-js/issues/68, or mute the thread https://github.com/notifications/unsubscribe-auth/AA6KbNMgpEjYDo1ixFDZY40krLWmtz5Hks5uN3PzgaJpZM4VvkJC .

-- Peter Lee Chief Executive Officer Corenova Technologies, Inc. +1-310-400-6450 linkedin.com/in/peter-k-lee

sekur commented 6 years ago

Sorry about the format issues in my earlier response, using email reply didn’t work out as well as I expected.

quantang commented 6 years ago

Hi @saintkepha

Thanks a lot for your reply.

For the second issue, here is my test code:

const Yang = require('yang-js');

const networkData = {
    "ietf-network:networks": {
        "network": [{
            "network-types": {
            },
            "network-id": "physical",
            "node": [{
                "node-id": "0000.0001.0000",
                "ietf-network-topology:termination-point": [{
                    "tp-id": "1.0.1",
                }]
            }, {
                "node-id": "0000.0002.0000",
                "ietf-network-topology:termination-point": [{
                    "tp-id": "2.0.1"
                }]
            }],
            "ietf-network-topology:link": [{
                "link-id": "abc",
                "source": {
                    "source-node": "0000.0001.0000",
                    "source-tp": "1.0.1"
                },
                "destination": {
                    "dest-node": "0000.0002.0000",
                    "dest-tp": "2.0.1"
                }
            }]
        }]
    }
};

const Topo = Yang.import('ietf-network-topology');
const model = Topo.eval(networkData);

You will get the following error if you have fixed the list [index] issue (I just made a little change in schema file to work it around):

  yang:property [ietf-network/ietf-network:networks/network/0] [find] ietf-network:node/node-id +0ms
  yang:property [ietf-network/ietf-network:networks/network/0] [find] using .['ietf-network:node']['node-id'] +0ms
  yang:property [ietf-network/ietf-network:networks/network/0] [find] apply .['ietf-network:node']['node-id'] +0ms
  yang:property { 'network-types': [Getter/Setter],
  yang:property   'network-id': [Getter/Setter],
  yang:property   node: [Getter/Setter],
  yang:property   'ietf-network-topology:link': [Getter/Setter] } +0ms

/home/quant/Projects/yang-topology/node_modules/yang-js/lib/lang/typedefs.js:274
          err = new Error("[" + this.tag + "] " + ctx.name + " is invalid for '" + value + "' (not found in " + this.path.tag + ")");
                ^
0000.0002.0000
    at Function.construct (/home/quant/Projects/yang-topology/node_modules/yang-js/lib/lang/typedefs.js:274:17)

In order to make it run, you need the following config in package.json file:

  "models": {
    "ietf-yang-types": "yang-js",
    "ietf-inet-types": "yang-js",
    "ietf-network": "./yang/ietf-network@2017-12-18.yang",
    "ietf-network-topology": "./yang/ietf-network-topology@2017-12-18.yang"
  }

BTW, as these schema files are based on yang version 1.1, so you need to remove the "reference" from "import" statement to make it run, which would be another issue you may need deal with. :smile:

sekur commented 6 years ago

Thanks @quantang. I’ll take a closer look after I’m back from vacation on Wednesday.

sekur commented 6 years ago

Issue number 1 has been fixed and confirmed via test case for list.