Fix yang source provisioning from MD-SAL netconf northbound
[netconf.git] / opendaylight / netconf / mdsal-netconf-connector / src / main / java / org / opendaylight / netconf / mdsal / connector / MdsalNetconfOperationServiceFactory.java
index d4f0c9ef4292aa97d081dd3e34bdde8b320796fb..4e98d2938e1456d03756ced4a102315d31b94a14 100644 (file)
@@ -8,8 +8,13 @@
 
 package org.opendaylight.netconf.mdsal.connector;
 
+import com.google.common.base.Charsets;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.io.CharStreams;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -18,13 +23,18 @@ import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.config.util.capability.YangModuleCapability;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
 import org.opendaylight.controller.sal.core.api.Consumer;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.netconf.api.monitoring.CapabilityListener;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,9 +46,11 @@ public class MdsalNetconfOperationServiceFactory implements NetconfOperationServ
     private DOMDataBroker dataBroker = null;
     private DOMRpcService rpcService = null;
     private final CurrentSchemaContext currentSchemaContext;
+    private final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProviderDependency;
 
-    public MdsalNetconfOperationServiceFactory(final SchemaService schemaService) {
-        this.currentSchemaContext = new CurrentSchemaContext(Preconditions.checkNotNull(schemaService));
+    public MdsalNetconfOperationServiceFactory(final SchemaService schemaService, final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProviderDependency) {
+        this.rootSchemaSourceProviderDependency = rootSchemaSourceProviderDependency;
+        this.currentSchemaContext = new CurrentSchemaContext(Preconditions.checkNotNull(schemaService), rootSchemaSourceProviderDependency);
     }
 
     @Override
@@ -54,10 +66,10 @@ public class MdsalNetconfOperationServiceFactory implements NetconfOperationServ
 
     @Override
     public Set<Capability> getCapabilities() {
-        return transformCapabilities(currentSchemaContext.getCurrentContext());
+        return transformCapabilities(currentSchemaContext.getCurrentContext(), rootSchemaSourceProviderDependency);
     }
 
-    static Set<Capability> transformCapabilities(final SchemaContext currentContext) {
+    static Set<Capability> transformCapabilities(final SchemaContext currentContext, final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProviderDependency) {
         final Set<Capability> capabilities = new HashSet<>();
 
         // Added by netconf-impl by default
@@ -65,12 +77,12 @@ public class MdsalNetconfOperationServiceFactory implements NetconfOperationServ
 
         final Set<Module> modules = currentContext.getModules();
         for (final Module module : modules) {
-            Optional<YangModuleCapability> cap = moduleToCapability(module);
+            Optional<YangModuleCapability> cap = moduleToCapability(module, rootSchemaSourceProviderDependency);
             if(cap.isPresent()) {
                 capabilities.add(cap.get());
             }
             for (final Module submodule : module.getSubmodules()) {
-                cap = moduleToCapability(submodule);
+                cap = moduleToCapability(submodule, rootSchemaSourceProviderDependency);
                 if(cap.isPresent()) {
                     capabilities.add(cap.get());
                 }
@@ -80,13 +92,36 @@ public class MdsalNetconfOperationServiceFactory implements NetconfOperationServ
         return capabilities;
     }
 
-    private static Optional<YangModuleCapability> moduleToCapability(final Module module) {
-        final String source = module.getSource();
+    private static Optional<YangModuleCapability> moduleToCapability(
+            final Module module, final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProviderDependency) {
+
+        final SourceIdentifier moduleSourceIdentifier = SourceIdentifier.create(module.getName(),
+                (SimpleDateFormatUtil.DEFAULT_DATE_REV == module.getRevision() ? Optional.<String>absent() :
+                        Optional.of(SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision()))));
+
+        InputStream sourceStream = null;
+        String source;
+        try {
+            sourceStream = rootSchemaSourceProviderDependency.getSource(moduleSourceIdentifier).checkedGet().openStream();
+            source = CharStreams.toString(new InputStreamReader(sourceStream, Charsets.UTF_8));
+        } catch (IOException | SchemaSourceException e) {
+            LOG.warn("Ignoring source for module {}. Unable to read content", moduleSourceIdentifier, e);
+            source = null;
+        }
+
+        try {
+            if (sourceStream != null) {
+                sourceStream.close();
+            }
+        } catch (IOException e) {
+            LOG.warn("Error closing yang source stream {}. Ignoring", moduleSourceIdentifier, e);
+        }
+
         if(source !=null) {
             return Optional.of(new YangModuleCapability(module, source));
         } else {
             LOG.warn("Missing source for module {}. This module will not be available from netconf server",
-                    module);
+                    moduleSourceIdentifier);
         }
         return Optional.absent();
     }