Details
-
Bug
-
Status: Resolved
-
Medium
-
Resolution: Done
-
None
-
None
-
None
Description
Yangtools parser doesn t inherit parent config statement if it comes from augmentations. Meaning if we are augmenting container that is "config false;" all the nodes in that augmentation should be config false too without need of setting them to config false; but they are not if they are not explicitly set to config false inside of augmentation statement.
The following code:
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.ServiceLoader; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.parser.api.YangParser; import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.slf4j.LoggerFactory; public class Main { private static final YangParserFactory PARSER_FACTORY; private static final Logger LOG = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); static { LOG.setLevel(Level.INFO); final Iterator<YangParserFactory> it = ServiceLoader.load(YangParserFactory.class).iterator(); if (!it.hasNext()) { throw new IllegalStateException("No YangParserFactory found"); } PARSER_FACTORY = it.next(); } public static void main(final String[] args) throws IOException, YangParserException { final YangParser parser = PARSER_FACTORY.createParser(); // add sources with its dependents parser.addSource(YangTextSchemaSource.forFile(new File("<path_to_file>/ietf-ipv4-unicast-routing@2018-03-13.yang"))); parser.addLibSource(YangTextSchemaSource.forFile(new File("<path_to_file>/ietf-routing@2018-03-13.yang"))); parser.addLibSource(YangTextSchemaSource.forFile(new File("<path_to_file>/ietf-interfaces@2018-02-20.yang"))); parser.addLibSource(YangTextSchemaSource.forFile(new File("<path_to_file>/ietf-yang-types@2013-07-15.yang"))); parser.addLibSource(YangTextSchemaSource.forFile(new File("<path_to_file>/ietf-inet-types@2013-07-15.yang"))); // build schema context final SchemaContext schemaContext = parser.buildSchemaContext(); // get module final Module module = schemaContext.findModule("ietf-ipv4-unicast-routing", Revision.of("2018-03-13")).get(); // iterate through all the augmentations for(final AugmentationSchemaNode augNode : module.getAugmentations()) { // build augmentation path final StringBuilder pathBuilder = new StringBuilder(); for (QName qname : augNode.getTargetPath().getPathFromRoot()) { pathBuilder.append('/') .append(qname.getLocalName()); } LOG.info("augmentation path: " + pathBuilder.toString()); // iterate through nodes in each augmentation for(DataSchemaNode node :augNode.getChildNodes()){ final String name = node.getQName().getLocalName(); final boolean isConfig = node.isConfiguration(); LOG.info("node " + name + " isConfig " + isConfig); } } } }
Please change <path_to_file> to wherever your file is. you can find these files in this github repo.
So this code returns output like this.
12:59:16.253 [main] INFO ROOT - augmentation path: /routing/ribs/rib/routes/route 12:59:16.263 [main] INFO ROOT - node destination-prefix isConfig true 12:59:16.263 [main] INFO ROOT - augmentation path: /routing/ribs/rib/routes/route/next-hop/next-hop-options/simple-next-hop 12:59:16.263 [main] INFO ROOT - node next-hop-address isConfig true 12:59:16.263 [main] INFO ROOT - augmentation path: /routing/ribs/rib/routes/route/next-hop/next-hop-options/next-hop-list/next-hop-list/next-hop 12:59:16.263 [main] INFO ROOT - node address isConfig true
but already in first augmentation we can see that /routing/ribs/rib/routes/route
is following in yang.
container routes {
config false;
description
"Current contents of the RIB.";
list route {
description
"A RIB route entry. This data node MUST be augmented
with information specific to routes of each address
family.";
Right on the second line container routes is of config false; which means that list route must be config false too and everything in it even if we augmenting. but our node in that augmentation is node destination-prefix and its isConfig is set to true.