[NETCONF-746] YANG patch request on NETCONF mountpoint is not atomic Created: 03/Dec/20  Updated: 02/Jul/21  Resolved: 02/Jul/21

Status: Resolved
Project: netconf
Component/s: netconf
Affects Version/s: Magnesium, Aluminium
Fix Version/s: 1.13.1

Type: Bug Priority: Medium
Reporter: Samuel Kontris Assignee: Oleksii Mozghovyi
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Blocks
is blocked by NETCONF-705 Netconf lock/unlock issue when multip... Resolved

 Description   

The RFC8072 states in the introduction part, that:
"For any protocol that supports the YANG Patch media type, if the entire patch document cannot be successfully applied, then the server MUST NOT apply any of the changes."

This is not the case when executing YANG patch request on NETCONF mountpoint.

If YANG patch request contains for example three edits - edit1, edit2 and edit3. Then if edit1 is successfully executed but edit2 fails, then request execution will stop (edit3 will not be executed). However data modification from edit1 will be applied anyway.

Atomicity works as it should when executing YANG patch request on ODL datastore. Problem seems to be only when working with mountpoints.

Actual example (tested with RFC8040 and on Aluminium SR0 and Magnesium SR2 versions):
Test YANG model:

module test-model {
  namespace "test-ns";
  prefix test-model;

  container container-root {
    leaf leaf-lvl1 {
      type string;
    }
    container container-lvl1 {
      leaf leaf-lvl2 {
        type string;
      }
      list list-lvl2 {
        key list-lvl2-key;
        leaf list-lvl2-key {
          type string;
        }
        leaf leaf-lvl2 {
          type string;
        }
      }
    }
  }
}

Mountpoint datastore content before executing YANG patch (note that "leaf-lvl1" contains value "something"):

{
    "test-model:container-root": {
        "leaf-lvl1": "something",
        "container-lvl1": {
            "list-lvl2": [
                {
                    "list-lvl2-key": "key",
                    "leaf-lvl2": "something"
                },
                {
                    "list-lvl2-key": "key2",
                    "leaf-lvl2": "something"
                }
            ]
        }
    }
}

YANG patch request payload - edit1 and edit3 are operation "replace", but edit2 is operation "create", which fails, because data already exists (note that we are trying to rewrite leaf values from "something" to "something-else"):

{
    "ietf-yang-patch:yang-patch": {
        "patch-id": "patch1",
        "comment": "Edit mountpoint data",
        "edit": [
            {
                "edit-id": "edit1",
                "operation": "replace",
                "target": "/test-model:container-root/test-model:leaf-lvl1",
                "value": {
                    "leaf-lvl1": "something-else"
                }
            },
            {
                "edit-id": "edit2",
                "operation": "create",
                "target": "/test-model:container-root/test-model:container-lvl1/test-model:list-lvl2[test-model:list-lvl2-key='key']",
                "value": {
                    "test-model:list-lvl2": {
                        "list-lvl2-key": "key",
                        "leaf-lvl2": "something-else"
                    }
                }
            },
            {
                "edit-id": "edit3",
                "operation": "replace",
                "target": "/test-model:container-root/test-model:container-lvl1/test-model:list-lvl2[test-model:list-lvl2-key='key2']",
                "value": {
                    "test-model:list-lvl2": {
                        "list-lvl2-key": "key2",
                        "leaf-lvl2": "something-else"
                    }
                }
            }
        ]
    }
}

Response from request above:

{
    "ietf-yang-patch:yang-patch-status": {
        "patch-id": "patch1",
        "edit-status": {
            "edit": [
                {
                    "edit-id": "edit1",
                    "ok": [
                        null
                    ]
                },
                {
                    "edit-id": "edit2",
                    "errors": {
                        "error": [
                            {
                                "error-type": "protocol",
                                "error-tag": "data-exists",
                                "error-path": "/(test-ns)container-root/container-lvl1/list-lvl2/list-lvl2[{(test-ns)list-lvl2-key=key}]",
                                "error-message": "Data already exists"
                            }
                        ]
                    }
                }
            ]
        }
    }
}

Mountpoint datastore content AFTER executing YANG patch (note that "leaf-lvl1" contains now value "something-else" but other leaves still contain value "something"):

{
    "test-model:container-root": {
        "leaf-lvl1": "something-else",
        "container-lvl1": {
            "list-lvl2": [
                {
                    "list-lvl2-key": "key",
                    "leaf-lvl2": "something"
                },
                {
                    "list-lvl2-key": "key2",
                    "leaf-lvl2": "something"
                }
            ]
        }
    }
}

 

According to response, edit1 was executed successfully but edit2 failed with "Data already exists" error message. There was not attempt to execute edit3.

However, request actually changed value of "leaf-lvl1" from "something" to "something-else" even when edit2 failed.



 Comments   
Comment by Oleksii Mozghovyi [ 09/Mar/21 ]

I've pushed changes, which should fix this issue. Commit operation now takes into account the results of previously executed operations inside the RESTCONF transaction and sends discard-changes if any of those fails.

Comment by Oleksii Mozghovyi [ 26/May/21 ]

This issue has been fixed with the following commit: https://git.opendaylight.org/gerrit/c/netconf/+/95359

Generated at Wed Feb 07 20:15:47 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.