Uploaded image for project: 'yangtools'
  1. yangtools
  2. YANGTOOLS-1404

Deviation of augmented node causes NPE

    XMLWordPrintable

Details

    • Bug
    • Status: Resolved
    • Medium
    • Resolution: Done
    • 6.0.0, 7.0.0, 7.0.9, 6.0.12, 7.0.14
    • 8.0.0, 7.0.15
    • model-util

    Description

      An augmented data node changed by deviation (not-supported) can cause a null pointer exception or fail to verify non-null requirement while writing NormalizedNode.

      For example, the following 3 models together have two leaves (bar & qux) under foo - baz is removed by deviate.yang:

      orig.yang

      module orig {
          namespace "urn:orig";
          prefix orig;
      
          container foo {
              leaf bar {
                  type string;
              }
          }
      }
      

      aug.yang

      module aug {
          namespace "urn:aug";
          prefix aug;
      
          import orig {
              prefix orig;
          }
      
          augment /orig:foo {
              leaf baz {
                  type string;
              }
      
              leaf qux {
                  type string;
              }
          }
      }
      

      deviate.yang

      module deviate {
          namespace "urn:deviate";
          prefix dev;
      
          import orig {
              prefix orig;
          }
          import aug {
              prefix aug;
          }
      
          deviation /orig:foo/aug:baz {
              deviate not-supported;
          }
      }
      

      When PUT request is submitted like below:

      PUT /rests/data/network-topology:network-topology/topology=topology-netconf/node=node1/yang-ext:mount/orig:foo
      
      {
          "orig:foo": {
              "bar": "apple",
              "aug:qux": "orange"
          }
      }
      

      This causes the following exception although status code of 201 is returned by the controller:

      yangtools 7.0.12

      2022-02-03T23:12:08,009 | ERROR | opendaylight-cluster-data-akka.actor.default-dispatcher-4 | OneForOneStrategy                | 213 - org.opendaylight.controller.repackaged-akka - 4.0.8 | No child matching (urn:aug)baz found
      com.google.common.base.VerifyException: No child matching (urn:aug)baz found
      	at com.google.common.base.Verify.verify(Verify.java:124) ~[bundleFile:?]
      	at com.google.common.base.Verify.verifyNotNull(Verify.java:500) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.model.api.DataNodeContainer.getDataChildByName(DataNodeContainer.java:84) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema.create(EffectiveAugmentationSchema.java:67) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.util.NormalizedNodeStreamWriterStack.startAugmentationNode(NormalizedNodeStreamWriterStack.java:301) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.codec.xml.SchemaAwareXMLStreamNormalizedNodeStreamWriter.startAugmentationNode(SchemaAwareXMLStreamNormalizedNodeStreamWriter.java:136) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter.startAugmentationNode(ForwardingNormalizedNodeStreamWriter.java:87) ~[bundleFile:?]
      	at org.opendaylight.yangtools.rfc7952.data.util.NormalizedNodeStreamWriterMetadataDecorator.startAugmentationNode(NormalizedNodeStreamWriterMetadataDecorator.java:121) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.wasProcessedAsCompositeNode(NormalizedNodeWriter.java:222) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.write(NormalizedNodeWriter.java:102) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.writeChildren(NormalizedNodeWriter.java:189) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.wasProcessedAsCompositeNode(NormalizedNodeWriter.java:205) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.write(NormalizedNodeWriter.java:102) ~[bundleFile:?]
      	at org.opendaylight.yangtools.rfc7952.data.util.NormalizedMetadataWriter.write(NormalizedMetadataWriter.java:114) ~[bundleFile:?]
      	at org.opendaylight.netconf.util.NetconfUtil.writeNormalizedNode(NetconfUtil.java:182) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.createEditConfigAnyxml(NetconfMessageTransformUtil.java:377) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.util.NetconfRpcStructureTransformer.createEditConfigStructure(NetconfRpcStructureTransformer.java:64) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps.createEditConfigStructure(NetconfBaseOps.java:431) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.sal.AbstractNetconfDataTreeService.replace(AbstractNetconfDataTreeService.java:297) ~[bundleFile:?]
      	at org.opendaylight.netconf.topology.singleton.impl.actors.NetconfDataTreeServiceActor.onReceive(NetconfDataTreeServiceActor.java:104) ~[?:?]
      	at akka.actor.UntypedAbstractActor$$anonfun$receive$1.applyOrElse(AbstractActor.scala:332) ~[bundleFile:?]
      	at akka.actor.Actor.aroundReceive(Actor.scala:537) ~[bundleFile:?]
      	at akka.actor.Actor.aroundReceive$(Actor.scala:535) ~[bundleFile:?]
      	at akka.actor.AbstractActor.aroundReceive(AbstractActor.scala:220) ~[bundleFile:?]
      	at akka.actor.ActorCell.receiveMessage(ActorCell.scala:580) [bundleFile:?]
      	at akka.actor.ActorCell.invoke(ActorCell.scala:548) [bundleFile:?]
      	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270) [bundleFile:?]
      	at akka.dispatch.Mailbox.run(Mailbox.scala:231) [bundleFile:?]
      	at akka.dispatch.Mailbox.exec(Mailbox.scala:243) [bundleFile:?]
      	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) [?:?]
      	at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) [?:?]
      	at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) [?:?]
      	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) [?:?]
      	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) [?:?]
      

      yangtools 6.0.12:

      2022-02-03T23:47:18,614 | ERROR | opendaylight-cluster-data-akka.actor.default-dispatcher-6 | OneForOneStrategy                | 212 - org.opendaylight.controller.repackaged-akka - 3.0.16 | null
      java.lang.NullPointerException: null
      	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:878) ~[bundleFile:?]
      	at com.google.common.collect.ImmutableSet.construct(ImmutableSet.java:199) ~[bundleFile:?]
      	at com.google.common.collect.ImmutableSet.copyOf(ImmutableSet.java:236) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema.<init>(EffectiveAugmentationSchema.java:46) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema.create(EffectiveAugmentationSchema.java:69) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker.startAugmentationNode(SchemaTracker.java:262) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.codec.xml.SchemaAwareXMLStreamNormalizedNodeStreamWriter.startAugmentationNode(SchemaAwareXMLStreamNormalizedNodeStreamWriter.java:133) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter.startAugmentationNode(ForwardingNormalizedNodeStreamWriter.java:87) ~[bundleFile:?]
      	at org.opendaylight.yangtools.rfc7952.data.util.NormalizedNodeStreamWriterMetadataDecorator.startAugmentationNode(NormalizedNodeStreamWriterMetadataDecorator.java:121) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.wasProcessedAsCompositeNode(NormalizedNodeWriter.java:228) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.write(NormalizedNodeWriter.java:103) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.writeChildren(NormalizedNodeWriter.java:190) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.wasProcessedAsCompositeNode(NormalizedNodeWriter.java:206) ~[bundleFile:?]
      	at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.write(NormalizedNodeWriter.java:103) ~[bundleFile:?]
      	at org.opendaylight.yangtools.rfc7952.data.util.NormalizedMetadataWriter.write(NormalizedMetadataWriter.java:114) ~[bundleFile:?]
      	at org.opendaylight.netconf.util.NetconfUtil.writeNormalizedNode(NetconfUtil.java:180) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.createEditConfigAnyxml(NetconfMessageTransformUtil.java:414) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.util.NetconfRpcStructureTransformer.createEditConfigStructure(NetconfRpcStructureTransformer.java:64) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps.createEditConfigStrcture(NetconfBaseOps.java:431) ~[bundleFile:?]
      	at org.opendaylight.netconf.sal.connect.netconf.sal.AbstractNetconfDataTreeService.replace(AbstractNetconfDataTreeService.java:298) ~[bundleFile:?]
      	at org.opendaylight.netconf.topology.singleton.impl.actors.NetconfDataTreeServiceActor.onReceive(NetconfDataTreeServiceActor.java:104) ~[?:?]
      	at akka.actor.UntypedAbstractActor$$anonfun$receive$1.applyOrElse(AbstractActor.scala:332) ~[bundleFile:?]
      	at akka.actor.Actor.aroundReceive(Actor.scala:537) ~[bundleFile:?]
      	at akka.actor.Actor.aroundReceive$(Actor.scala:535) ~[bundleFile:?]
      	at akka.actor.AbstractActor.aroundReceive(AbstractActor.scala:220) ~[bundleFile:?]
      	at akka.actor.ActorCell.receiveMessage(ActorCell.scala:580) [bundleFile:?]
      	at akka.actor.ActorCell.invoke(ActorCell.scala:548) [bundleFile:?]
      	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270) [bundleFile:?]
      	at akka.dispatch.Mailbox.run(Mailbox.scala:231) [bundleFile:?]
      	at akka.dispatch.Mailbox.exec(Mailbox.scala:243) [bundleFile:?]
      	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) [?:?]
      	at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) [?:?]
      	at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) [?:?]
      	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) [?:?]
      	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) [?:?]
      

      Note that the problem goes away If augmentation is done separately for each node, i.e. if the following is used for aug.yang instead:

      module aug {
          namespace "urn:aug";
          prefix aug;
      
          import orig {
              prefix orig;
          }
      
          augment /orig:foo {
              leaf baz {
                  type string;
              }
          }
      
          augment /orig:foo {
              leaf qux {
                  type string;
              }
          }
      }
      

      Attachments

        1. aug.yang
          0.2 kB
        2. deviate.yang
          0.2 kB
        3. karaf.log
          394 kB
        4. orig.yang
          0.1 kB
        5. Steps to reproduce.odt
          18 kB

        Issue Links

          # Subject Branch Project Status CR V

          Activity

            People

              rovarga Robert Varga
              sangwookha Sangwook Ha
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: