Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

0

YANG import catch-22???

asked 2017-08-17 14:26:15 -0700

mdeazley gravatar image

updated 2017-08-17 15:55:09 -0700

Q: How are imports resolved in the yangtools YANG parser?

More explicitly: How can I resolve the imports in a YANG file if I cannot parse it to find the imports??? Seems like a catch-22!!!

I'm trying to write a basic YANG parser using the directions found in the docs directory within the yangtools project.

Example: It is giving me a set of nested exceptions that I have summarized below:

Error Parsing yang/vendor/cisco/nx/7.0-3-I6-1/openconfig-types.yang:
  - Some of SOURCE_PRE_LINKAGE modifiers for statements were not resolved. 
  - Yang model processing phase SOURCE_PRE_LINKAGE failed [at yang/vendor/cisco/nx/7.0-3-I6-1/openconfig-types.yang:1:0]
 - Imported module [openconfig-extensions] was not found. [at yang/vendor/cisco/nx/7.0-3-I6-1/openconfig-types.yang:9:2]

My Code:

package doctoryang.rest.util;

import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class YangParser {

    private String filePath;

    public YangParser(String filePath) {
    this.filePath = filePath;
    }

    public List<String> parse() {
    try {
        StatementStreamSource statementStreamSource = YangStatementStreamSource.create(YangTextSchemaSource.forFile(new File(filePath)));
        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
        reactor.addSource(statementStreamSource);

        SchemaContext schemaContext = reactor.buildEffective();    <<< ERROR OCCURS HERE <<<
        Set<Module> modules = schemaContext.getModules();
        ArrayList<String> l = new ArrayList<>();
        l.addAll(modules.stream().map(m -> m.getName()).collect(Collectors.toList()));
        return l;
    } catch (Exception e) {
        StringBuilder sb = new StringBuilder();
        sb.append("Error Parsing ");
        sb.append(filePath);
        Throwable cause = e;
        while (cause != null) {
            sb.append(" cause:");
            sb.append(cause.getMessage());
            cause = cause.getCause();
        }
        throw new IllegalStateException(sb.toString(), e);
    }
    }
}

I see in the test code

      yangtools/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/ImportResolutionBasicTest.java

that the entire graph of imports is specified:

@Test
public void inImportOrderTest() throws SourceException, ReactorException {
    BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
    reactor.addSources(ROOT_WITHOUT_IMPORT, IMPORT_ROOT, IMPORT_DERIVED);
    EffectiveModelContext result = reactor.build();
    assertNotNull(result);
}

Is knowledge of the entire import graph of a given YANG file a pre-condition to parsing the given YANG file using the 'reactor'?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
0

answered 2017-10-09 14:53:13 -0700

Robert Varga gravatar image

SOURCEPRELINKAGE performs partial parsing, just enough to understand import/namespace/revision declarations, after which it knows what needs to be imported (which is SOURCE_LINKAGE).

As noted, the import is not satisfied in the list of modules you are importing -- hance adding openconfig-extensions.yang to the reactor should make it succeed.

There is no way to ignore an import statement.

edit flag offensive delete publish link more
0

answered 2017-10-03 07:51:43 -0700

I've some problem, this is my code :

pom.xml file :

<!-- opendaylight Yangtools -->
<dependency>
    <groupId>org.opendaylight.yangtools</groupId>
    <artifactId>yang-parser-impl</artifactId>
    <version>1.2.0-SNAPSHOT</version>
    <type>jar</type>
</dependency>        
<dependency>
    <groupId>org.opendaylight.yangtools</groupId>
    <artifactId>yang-parser-api</artifactId>
    <version>1.2.0-SNAPSHOT</version>
    <type>jar</type>
</dependency>
<dependency>
    <groupId>org.opendaylight.yangtools</groupId>
    <artifactId>yang-model-api</artifactId>
    <version>1.2.0-SNAPSHOT</version>
    <type>jar</type>
</dependency>

my java YangParser class :

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class YangParser {

    private static final Logger LOGGER = LoggerFactory.getLogger(YangParser.class);

    public YangParser() {    
    }

    public void parseModule(String file) throws IOException, YangSyntaxErrorException {   
        LOGGER.debug("Parse Yang module from file : " + file);

        try {
            File yang_file = new File(file);
            CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();            
            reactor.addSource(YangStatementStreamSource.create(
                YangTextSchemaSource.forFile(yang_file)));

            SchemaContext schemaContext = reactor.buildEffective();            

            Set<Module> modules = schemaContext.getModules();
            for (Module m : modules) {
                LOGGER.debug("Add YANG module : " + m.getName());
                LOGGER.debug("Namespace : " + m.getNamespace().toString());
            }

        }
        catch (ReactorException e) {
            throw new IllegalStateException("Parsing Yang module failed, error : " + e.getMessage());
        }
    }
}

How Can I solve this problem ? Can I configure ignoring import in yang file ? Thanks.

edit flag offensive delete publish link more
Login/Signup to Answer

Question Tools

Follow
1 follower

Stats

Asked: 2017-08-17 14:26:15 -0700

Seen: 26 times

Last updated: Oct 09