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

Deviation of augmented node causes NPE

XMLWordPrintable

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

      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;
              }
          }
      }
      

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

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

              Created:
              Updated:
              Resolved: