Add yanglib-rfc8525 52/83252/20
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 25 Jul 2019 14:04:28 +0000 (16:04 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 26 Jul 2019 10:58:08 +0000 (12:58 +0200)
This adds the necessary support for constructing mount points
described through RFC8525 (NMDA) YANG Library.

JIRA: MDSAL-463
Change-Id: I22b4449f544e3d0225bac59fa3928ecb434f8f13
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
artifacts/pom.xml
binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java
features/features-mdsal-experimental/pom.xml
features/odl-mdsal-exp-yanglib-rfc8525/pom.xml [new file with mode: 0644]
features/pom.xml
yanglib/mdsal-yanglib-rfc8525/pom.xml [new file with mode: 0644]
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/MountPointContextFactoryImpl.java [new file with mode: 0644]
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/SimpleStrategy.java [new file with mode: 0644]
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupport.java [new file with mode: 0644]
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupportFactory.java [new file with mode: 0644]
yanglib/pom.xml

index afae64cb8d72958cc8288892ead2add298773d75..8b235154226d93f9cf59d2896cff2875b125ed96 100644 (file)
                 <artifactId>mdsal-yanglib-rfc7895</artifactId>
                 <version>0.9.3-SNAPSHOT</version>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.mdsal</groupId>
+                <artifactId>mdsal-yanglib-rfc8525</artifactId>
+                <version>0.9.3-SNAPSHOT</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>odl-mdsal-exp-yanglib-api</artifactId>
                 <classifier>features</classifier>
                 <type>xml</type>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>odl-mdsal-exp-yanglib-rfc8525</artifactId>
+                <version>0.9.3-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
 
             <!-- MODELS -->
             <dependency>
index e909fc0847dcdacf52805e9fa761d5fa92fa332b..80b336f1f1087385fbd7d1c0a899e37c59ac0502 100644 (file)
@@ -189,6 +189,7 @@ public final class BindingReflections {
         return Optional.empty();
     }
 
+    // FIXME: 4.0.0: check that the QName is actually resolved, i.e. guarantee @NonNull here
     public static QName getQName(final Class<? extends BaseIdentity> context) {
         return findQName(context);
     }
index 45ccf0c99c53424502b02d6657243b4ccefa5140..6903063c8783e55301d7dac78ba7827908defdb3 100644 (file)
             <classifier>features</classifier>
             <type>xml</type>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>odl-mdsal-exp-yanglib-rfc8525</artifactId>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
     </dependencies>
 </project>
diff --git a/features/odl-mdsal-exp-yanglib-rfc8525/pom.xml b/features/odl-mdsal-exp-yanglib-rfc8525/pom.xml
new file mode 100644 (file)
index 0000000..d7471b5
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.mdsal</groupId>
+        <artifactId>feature-parent</artifactId>
+        <version>4.0.3-SNAPSHOT</version>
+        <relativePath>../feature-parent</relativePath>
+    </parent>
+
+    <artifactId>odl-mdsal-exp-yanglib-rfc8525</artifactId>
+    <version>0.9.3-SNAPSHOT</version>
+    <packaging>feature</packaging>
+    <name>OpenDaylight :: MD-SAL :: RFC8525 YANG Library</name>
+    <description>MD-SAL YANG Library (RFC8525)</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>odl-mdsal-exp-yanglib-api</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>odl-mdsal-model-rfc8525</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>odl-mdsal-binding-runtime</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-yanglib-rfc8525</artifactId>
+        </dependency>
+    </dependencies>
+</project>
index 51e3a9ffdfe61fd8b02929d13b63b67f3601c2d4..745de3a7784fba1d7da2a4d0588240bf3159b805 100644 (file)
@@ -57,6 +57,7 @@
         <!-- YANG (Module) Library -->
         <module>odl-mdsal-exp-yanglib-api</module>
         <module>odl-mdsal-exp-yanglib-rfc7895</module>
+        <module>odl-mdsal-exp-yanglib-rfc8525</module>
 
         <!-- Models -->
         <!-- Standards -->
diff --git a/yanglib/mdsal-yanglib-rfc8525/pom.xml b/yanglib/mdsal-yanglib-rfc8525/pom.xml
new file mode 100644 (file)
index 0000000..75b6f22
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.mdsal</groupId>
+        <artifactId>dom-parent</artifactId>
+        <version>4.0.3-SNAPSHOT</version>
+        <relativePath>../../dom/dom-parent</relativePath>
+    </parent>
+
+    <artifactId>mdsal-yanglib-rfc8525</artifactId>
+    <version>0.9.3-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-yanglib-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
+            <artifactId>rfc8525</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-dom-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-parser-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kohsuke.metainf-services</groupId>
+            <artifactId>metainf-services</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>blueprint-maven-plugin-annotation</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-parser-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Automatic-Module-Name>org.opendaylight.mdsal.yanglib.rfc8525</Automatic-Module-Name>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.aries.blueprint</groupId>
+                <artifactId>blueprint-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.github.spotbugs</groupId>
+                <artifactId>spotbugs-maven-plugin</artifactId>
+                <configuration>
+                    <failOnError>true</failOnError>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/mdsal.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/mdsal.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/MD-SAL:Main</url>
+        <tag>HEAD</tag>
+    </scm>
+</project>
diff --git a/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/MountPointContextFactoryImpl.java b/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/MountPointContextFactoryImpl.java
new file mode 100644 (file)
index 0000000..3e07178
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.yanglib.rfc8525;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
+import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
+import org.opendaylight.mdsal.yanglib.api.SchemaContextResolver;
+import org.opendaylight.mdsal.yanglib.api.SourceReference;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.datastores.rev180214.Operational;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.ModulesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.RevisionIdentifier;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibrary;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.CommonLeafs;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.CommonLeafsRevisionBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.Module.ConformanceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.ImportOnlyModule;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.ImportOnlyModuleRevisionBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.Module;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.Datastore;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.Schema;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
+import org.opendaylight.yangtools.rcf8528.data.util.AbstractMountPointContextFactory;
+import org.opendaylight.yangtools.rfc8528.data.api.MountPointContextFactory;
+import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier;
+import org.opendaylight.yangtools.rfc8528.data.api.YangLibraryConstants.ContainerName;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class MountPointContextFactoryImpl extends AbstractMountPointContextFactory {
+    private static final Logger LOG = LoggerFactory.getLogger(MountPointContextFactoryImpl.class);
+
+    @SuppressWarnings("deprecation")
+    private final BindingDataObjectCodecTreeNode<ModulesState> legacyCodec;
+    private final BindingDataObjectCodecTreeNode<YangLibrary> codec;
+    private final EffectiveModelContext yangLibContext;
+    private final SchemaContextResolver resolver;
+
+    MountPointContextFactoryImpl(final MountPointIdentifier mountId, final SchemaContextResolver resolver,
+            final EffectiveModelContext yangLibContext,
+            final BindingDataObjectCodecTreeNode<YangLibrary> codec,
+            final BindingDataObjectCodecTreeNode<ModulesState> legacyCodec) {
+        super(mountId);
+        this.resolver = requireNonNull(resolver);
+        this.yangLibContext = requireNonNull(yangLibContext);
+        this.codec = requireNonNull(codec);
+        this.legacyCodec = requireNonNull(legacyCodec);
+    }
+
+    @Override
+    protected MountPointContextFactory createContextFactory(final MountPointDefinition mountPoint) {
+        return new MountPointContextFactoryImpl(mountPoint.getIdentifier(), resolver, yangLibContext, codec,
+            legacyCodec);
+    }
+
+    @Override
+    protected Optional<SchemaContext> findSchemaForLibrary(final ContainerName containerName) {
+        switch (containerName) {
+            case RFC7895:
+            case RFC8525:
+                return Optional.of(yangLibContext);
+            default:
+                LOG.debug("Unhandled YANG library container {}", containerName);
+                return Optional.empty();
+        }
+    }
+
+    @Override
+    protected SchemaContext bindLibrary(final ContainerName containerName, final ContainerNode libData)
+            throws YangParserException {
+        switch (containerName) {
+            case RFC7895:
+                return bindLibrary(verifyNotNull(legacyCodec.deserialize(libData)));
+            case RFC8525:
+                return bindLibrary(verifyNotNull(codec.deserialize(libData)));
+            default:
+                throw new IllegalStateException("Unhandled container type " + containerName);
+        }
+    }
+
+    private @NonNull SchemaContext bindLibrary(final @NonNull YangLibrary yangLib) throws YangParserException {
+        final List<Datastore> datastores = yangLib.nonnullDatastore();
+        checkArgument(!datastores.isEmpty(), "No datastore defined");
+
+        final List<SourceReference> requiredSources = new ArrayList<>();
+        final List<SourceReference> librarySources = new ArrayList<>();
+        final HashSet<String> moduleSet = findModuleSet(yangLib, findSchemaName(datastores, Operational.QNAME));
+        for (ModuleSet modSet : yangLib.nonnullModuleSet()) {
+            if (moduleSet.remove(modSet.getName())) {
+                fillModules(librarySources, requiredSources, modSet);
+            }
+        }
+        checkArgument(moduleSet.isEmpty(), "Failed to resolve module sets %s", moduleSet);
+
+        return resolver.resolveSchemaContext(librarySources, requiredSources);
+    }
+
+    @SuppressWarnings("deprecation")
+    private @NonNull SchemaContext bindLibrary(final @NonNull ModulesState modState) throws YangParserException {
+        final List<SourceReference> requiredSources = new ArrayList<>();
+        final List<SourceReference> librarySources = new ArrayList<>();
+
+        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list
+                .Module module : modState.nonnullModule()) {
+            final SourceReference modRef = sourceRefFor(module, module.getSchema());
+
+            // TODO: take deviations/features into account
+
+            if (ConformanceType.Import == module.getConformanceType()) {
+                librarySources.add(modRef);
+            } else {
+                requiredSources.add(modRef);
+            }
+
+            for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list
+                    .module.Submodule submodule : module.nonnullSubmodule()) {
+                // Submodules go to library, as they are pulled in as needed
+                librarySources.add(sourceRefFor(submodule, submodule.getSchema()));
+            }
+        }
+
+        return resolver.resolveSchemaContext(librarySources, requiredSources);
+    }
+
+    private static String findSchemaName(final List<Datastore> datastores, final QName qname) {
+        final Iterator<Datastore> it = datastores.iterator();
+        final Datastore ds = it.next();
+
+        // FIXME: This is ugly, but it is the most compatible thing we can do without knowing the exact requested
+        //        datastore
+        if (it.hasNext() && !qname.equals(BindingReflections.getQName(ds.getName()))) {
+            do {
+                final Datastore next = it.next();
+                if (qname.equals(BindingReflections.getQName(ds.getName()))) {
+                    return next.getSchema();
+                }
+            } while (it.hasNext());
+        }
+
+        return ds.getSchema();
+    }
+
+    @SuppressWarnings("deprecation")
+    private static SourceReference sourceRefFor(final CommonLeafs obj, final Uri uri) {
+        final SourceIdentifier sourceId = RevisionSourceIdentifier.create(obj.getName().getValue(),
+            CommonLeafsRevisionBuilder.toYangCommon(obj.getRevision()));
+        if (uri != null) {
+            try {
+                return SourceReference.of(sourceId, new URL(uri.getValue()));
+            } catch (MalformedURLException e) {
+                LOG.debug("Ignoring invalid schema location {}", uri, e);
+            }
+        }
+
+        return SourceReference.of(sourceId);
+    }
+
+    private static HashSet<String> findModuleSet(final YangLibrary yangLib, final String schemaName) {
+        for (Schema schema : yangLib.nonnullSchema()) {
+            if (schemaName.equals(schema.getName())) {
+                return new HashSet<>(schema.getModuleSet());
+            }
+        }
+        throw new IllegalArgumentException("Failed to find moduleSet for " + schemaName);
+    }
+
+    private static void fillModules(final List<SourceReference> librarySources,
+            final List<SourceReference> requiredSources, final ModuleSet modSet) {
+        // TODO: take deviations/features into account
+
+        for (ImportOnlyModule mod : modSet.nonnullImportOnlyModule()) {
+            fillSource(librarySources, mod.getName(), ImportOnlyModuleRevisionBuilder.toYangCommon(mod.getRevision()),
+                mod.getLocation());
+            mod.nonnullSubmodule().forEach(sub -> {
+                fillSource(librarySources, sub.getName(), toYangCommon(sub.getRevision()), sub.getLocation());
+            });
+        }
+        for (Module mod : modSet.nonnullModule()) {
+            fillSource(requiredSources, mod.getName(), toYangCommon(mod.getRevision()), mod.getLocation());
+            mod.nonnullSubmodule().forEach(sub -> {
+                fillSource(librarySources, sub.getName(), toYangCommon(sub.getRevision()), sub.getLocation());
+            });
+        }
+    }
+
+    private static void fillSource(final List<SourceReference> sources, final YangIdentifier sourceName,
+            final Optional<Revision> revision, final List<Uri> uris) {
+        final SourceIdentifier sourceId = RevisionSourceIdentifier.create(sourceName.getValue(), revision);
+        final SourceReference sourceRef;
+        if (uris != null && uris.isEmpty()) {
+            final List<URL> locations = new ArrayList<>();
+            for (Uri uri : uris) {
+                try {
+                    locations.add(new URL(uri.getValue()));
+                } catch (MalformedURLException e) {
+                    LOG.debug("Ignoring invalid schema location {}", uri, e);
+                }
+            }
+            sourceRef = SourceReference.of(sourceId, locations);
+        } else {
+            sourceRef = SourceReference.of(sourceId);
+        }
+
+        sources.add(sourceRef);
+    }
+
+    private static Optional<Revision> toYangCommon(final @Nullable RevisionIdentifier revisionIdentifier) {
+        return revisionIdentifier == null ? Optional.empty() : Optional.of(Revision.of(revisionIdentifier.getValue()));
+    }
+
+}
diff --git a/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/SimpleStrategy.java b/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/SimpleStrategy.java
new file mode 100644 (file)
index 0000000..f2f2b0c
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.yanglib.rfc8525;
+
+import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.model.api.Type;
+
+final class SimpleStrategy implements ClassLoadingStrategy {
+    static final SimpleStrategy INSTANCE = new SimpleStrategy();
+
+    @Override
+    public Class<?> loadClass(final Type type) throws ClassNotFoundException {
+        return loadClass(type.getFullyQualifiedName());
+    }
+
+    @Override
+    public Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
+        return SimpleStrategy.class.getClassLoader().loadClass(fullyQualifiedName);
+    }
+}
diff --git a/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupport.java b/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupport.java
new file mode 100644 (file)
index 0000000..27148f1
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.yanglib.rfc8525;
+
+import static com.google.common.base.Verify.verifyNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.Collections2;
+import java.io.IOException;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.aries.blueprint.annotation.service.Reference;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
+import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.mdsal.yanglib.api.SchemaContextResolver;
+import org.opendaylight.mdsal.yanglib.api.YangLibSupport;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.$YangModuleInfoImpl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.ModulesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibrary;
+import org.opendaylight.yangtools.rfc8528.data.api.MountPointContextFactory;
+import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+
+@Beta
+@NonNullByDefault
+@Singleton
+public final class YangLibrarySupport implements YangLibSupport {
+    private final BindingDataObjectCodecTreeNode<YangLibrary> codec;
+    @SuppressWarnings("deprecation")
+    private final BindingDataObjectCodecTreeNode<ModulesState> legacyCodec;
+    private final EffectiveModelContext context;
+
+    @Inject
+    public YangLibrarySupport(final @Reference YangParserFactory parserFactory)
+            throws YangSyntaxErrorException, YangParserException, IOException {
+        final YangModuleInfo yangLibModule = $YangModuleInfoImpl.getInstance();
+
+        // FIXME: DEFAULT_MODE should not be necessary, but it seems blueprint is still b0rked
+        context = parserFactory.createParser(StatementParserMode.DEFAULT_MODE)
+                .addLibSources(Collections2.transform(yangLibModule.getImportedModules(),
+                    YangLibrarySupport::createSource))
+                .addSource(createSource(yangLibModule))
+                .buildEffectiveModel();
+        final BindingCodecTree codecTree = new BindingNormalizedNodeCodecRegistry(BindingRuntimeContext.create(
+            SimpleStrategy.INSTANCE, context)).getCodecContext();
+
+        this.codec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(YangLibrary.class)));
+        this.legacyCodec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(ModulesState.class)));
+    }
+
+    @Override
+    public MountPointContextFactory createMountPointContextFactory(final MountPointIdentifier mountId,
+            final SchemaContextResolver resolver) {
+        return new MountPointContextFactoryImpl(mountId, resolver, context, codec, legacyCodec);
+    }
+
+    private static YangTextSchemaSource createSource(final YangModuleInfo info) {
+        final QName name = info.getName();
+        return YangTextSchemaSource.delegateForByteSource(
+            RevisionSourceIdentifier.create(name.getLocalName(), name.getRevision()), info.getYangTextByteSource());
+    }
+}
diff --git a/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupportFactory.java b/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupportFactory.java
new file mode 100644 (file)
index 0000000..66b6370
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.yanglib.rfc8525;
+
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.mdsal.yanglib.api.YangLibSupport;
+import org.opendaylight.mdsal.yanglib.api.YangLibSupportFactory;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+
+@MetaInfServices
+@NonNullByDefault
+public final class YangLibrarySupportFactory implements YangLibSupportFactory {
+    @Override
+    public YangLibSupport createYangLibSupport(final YangParserFactory parserFactory)
+            throws YangSyntaxErrorException, YangParserException, IOException {
+        return new YangLibrarySupport(parserFactory);
+    }
+}
index ad0d5140f0b9c9496a909533b562696c43b5436b..36e572cf06a075115137f99adf40510b0cfedea3 100644 (file)
@@ -27,6 +27,7 @@
     <modules>
         <module>mdsal-yanglib-api</module>
         <module>mdsal-yanglib-rfc7895</module>
+        <module>mdsal-yanglib-rfc8525</module>
     </modules>
 
     <properties>