Fix yang source provisioning from MD-SAL netconf northbound 26/32226/3
authorMaros Marsalek <mmarsale@cisco.com>
Thu, 7 Jan 2016 13:10:22 +0000 (14:10 +0100)
committerMaros Marsalek <mmarsale@cisco.com>
Sat, 9 Jan 2016 10:12:52 +0000 (10:12 +0000)
Change-Id: Iab11d3780379e681d2d6228868e8b96cd894cb56
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/mapper/NetconfMdsalMapperModule.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/CurrentSchemaContext.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/MdsalNetconfOperationServiceFactory.java
opendaylight/netconf/mdsal-netconf-connector/src/main/yang/netconf-mdsal-mapper.yang
opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java
opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/RuntimeRpcTest.java
opendaylight/netconf/netconf-mdsal-config/src/main/resources/initial/08-netconf-mdsal.xml
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/MdsalOperationProvider.java
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/NetconfDeviceSimulator.java

index e8a5bac746e6edcc1b4a5d2bc193ada040149436..23993cfe60fb287818f1ef5afb3823afe0db25c7 100644 (file)
@@ -27,7 +27,7 @@ public class NetconfMdsalMapperModule extends org.opendaylight.controller.config
     @Override
     public java.lang.AutoCloseable createInstance() {
         final MdsalNetconfOperationServiceFactory mdsalNetconfOperationServiceFactory =
-            new MdsalNetconfOperationServiceFactory(getRootSchemaServiceDependency()) {
+            new MdsalNetconfOperationServiceFactory(getRootSchemaServiceDependency(), getRootSchemaSourceProviderDependency()) {
                 @Override
                 public void close() throws Exception {
                     super.close();
index 594cd73f145d15fec716a7c0486300ea05580bff..a45d5a63775787bbf1956c9f63ef013c723606ef 100644 (file)
@@ -19,18 +19,22 @@ import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
 
 public class CurrentSchemaContext implements SchemaContextListener, AutoCloseable {
     final AtomicReference<SchemaContext> currentContext = new AtomicReference<SchemaContext>();
     private final ListenerRegistration<SchemaContextListener> schemaContextListenerListenerRegistration;
     private final Set<CapabilityListener> listeners1 = Collections.synchronizedSet(Sets.<CapabilityListener>newHashSet());
+    private SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProvider;
 
     public SchemaContext getCurrentContext() {
         Preconditions.checkState(currentContext.get() != null, "Current context not received");
         return currentContext.get();
     }
 
-    public CurrentSchemaContext(final SchemaService schemaService) {
+    public CurrentSchemaContext(final SchemaService schemaService, final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProvider) {
+        this.rootSchemaSourceProvider = rootSchemaSourceProvider;
         schemaContextListenerListenerRegistration = schemaService.registerSchemaContextListener(this);
     }
 
@@ -38,7 +42,7 @@ public class CurrentSchemaContext implements SchemaContextListener, AutoCloseabl
     public void onGlobalContextUpdated(final SchemaContext schemaContext) {
         currentContext.set(schemaContext);
         // FIXME is notifying all the listeners from this callback wise ?
-        final Set<Capability> addedCaps = MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get());
+        final Set<Capability> addedCaps = MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get(), rootSchemaSourceProvider);
         for (final CapabilityListener listener : listeners1) {
             listener.onCapabilitiesChanged(addedCaps, Collections.<Capability>emptySet());
         }
@@ -52,7 +56,7 @@ public class CurrentSchemaContext implements SchemaContextListener, AutoCloseabl
     }
 
     public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
-        listener.onCapabilitiesChanged(MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get()), Collections.<Capability>emptySet());
+        listener.onCapabilitiesChanged(MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get(), rootSchemaSourceProvider), Collections.<Capability>emptySet());
         listeners1.add(listener);
         return new AutoCloseable() {
             @Override
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();
     }
index c787287da5f81660edea616d4a0455b1d8e3b25a..633a930e17dddc8e90418b42bd13741528738088 100644 (file)
@@ -36,6 +36,15 @@ module netconf-mdsal-mapper {
                 }
             }
 
+            container root-schema-source-provider {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity md-sal-dom:yang-text-source-provider;
+                    }
+                }
+            }
+
             container dom-broker {
                 uses config:service-ref {
                     refine type {
index f66bdcb6876b2f8da16380b463af4da36e3e0ce8..3a0f3572831b590b3f36967477cc7511d9861caf 100644 (file)
@@ -12,7 +12,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
 
+import com.google.common.util.concurrent.Futures;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringWriter;
@@ -37,6 +40,10 @@ import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.cluster.datastore.ConcurrentDOMDataBroker;
 import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
@@ -65,6 +72,9 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+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.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
@@ -116,8 +126,12 @@ public class NetconfMDSalMappingTest {
 
     private TransactionProvider transactionProvider = null;
 
+    @Mock
+    private SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
+
     @Before
     public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
 
         XMLUnit.setIgnoreWhitespace(true);
         XMLUnit.setIgnoreAttributeOrder(true);
@@ -138,7 +152,19 @@ public class NetconfMDSalMappingTest {
 
         final ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor);
         this.transactionProvider = new TransactionProvider(cdb, sessionIdForReporting);
-        this.currentSchemaContext = new CurrentSchemaContext(schemaService);
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+                final SourceIdentifier sId = (SourceIdentifier) invocationOnMock.getArguments()[0];
+                final YangTextSchemaSource yangTextSchemaSource =
+                        YangTextSchemaSource.delegateForByteSource(sId, ByteSource.wrap("module test".getBytes()));
+                return Futures.immediateCheckedFuture(yangTextSchemaSource);
+
+            }
+        }).when(sourceProvider).getSource(any(SourceIdentifier.class));
+
+        this.currentSchemaContext = new CurrentSchemaContext(schemaService, sourceProvider);
 
     }
 
index 243595d0eefb8814f5ff70eb04b0689051159f83..6bab4fc8500afaffebbe39140a0db6474bda44fb 100644 (file)
@@ -50,11 +50,11 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -69,6 +69,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+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.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
@@ -151,6 +154,8 @@ public class RuntimeRpcTest {
     private SchemaContextListener listener;
     @Mock
     private ListenerRegistration registration;
+    @Mock
+    private SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
 
     @Before
     public void setUp() throws Exception {
@@ -173,8 +178,19 @@ public class RuntimeRpcTest {
         XMLUnit.setIgnoreWhitespace(true);
         XMLUnit.setIgnoreAttributeOrder(true);
 
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+                final SourceIdentifier sId = (SourceIdentifier) invocationOnMock.getArguments()[0];
+                final YangTextSchemaSource yangTextSchemaSource =
+                        YangTextSchemaSource.delegateForByteSource(sId, ByteSource.wrap("module test".getBytes()));
+                return Futures.immediateCheckedFuture(yangTextSchemaSource);
+
+            }
+        }).when(sourceProvider).getSource(any(SourceIdentifier.class));
+
         this.schemaContext = parseSchemas(getYangSchemas());
-        this.currentSchemaContext = new CurrentSchemaContext(schemaService);
+        this.currentSchemaContext = new CurrentSchemaContext(schemaService, sourceProvider);
     }
 
     @Test
index 81add4d4522e9bce9f13f3692ba24008109b9259..ccd416379640f2e9fa0d668d9031cf1a301514b4 100644 (file)
                   <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
                   <name>yang-schema-service</name>
               </root-schema-service>
+              <root-schema-source-provider>
+                  <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:yang-text-source-provider</type>
+                  <name>yang-text-source-provider</name>
+              </root-schema-source-provider>
               <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper">
                   <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
                   <name>dom-broker</name>
index 25ebc579d7182a49d97330aada5ba696cc338277..605d7ba35fb6aa7c5de08e48397aa7b1c24b7974 100644 (file)
@@ -57,6 +57,8 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNo
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+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;
 
@@ -67,12 +69,14 @@ class MdsalOperationProvider implements NetconfOperationServiceFactory {
 
     private final Set<Capability> caps;
     private final SchemaContext schemaContext;
+    private SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
 
     public MdsalOperationProvider(final SessionIdProvider idProvider,
                                   final Set<Capability> caps,
-                                  final SchemaContext schemaContext) {
+                                  final SchemaContext schemaContext, final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
         this.caps = caps;
         this.schemaContext = schemaContext;
+        this.sourceProvider = sourceProvider;
     }
 
     @Override
@@ -93,7 +97,7 @@ class MdsalOperationProvider implements NetconfOperationServiceFactory {
 
     @Override
     public NetconfOperationService createService(String netconfSessionIdForReporting) {
-        return new MdsalOperationService(Long.parseLong(netconfSessionIdForReporting), schemaContext, caps);
+        return new MdsalOperationService(Long.parseLong(netconfSessionIdForReporting), schemaContext, caps, sourceProvider);
     }
 
     static class MdsalOperationService implements NetconfOperationService {
@@ -102,13 +106,15 @@ class MdsalOperationProvider implements NetconfOperationServiceFactory {
         private final Set<Capability> caps;
         private final SchemaService schemaService;
         private final DOMDataBroker dataBroker;
+        private SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
 
         public MdsalOperationService(final long currentSessionId,
                                      final SchemaContext schemaContext,
-                                     final Set<Capability> caps) {
+                                     final Set<Capability> caps, final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
             this.currentSessionId = currentSessionId;
             this.schemaContext = schemaContext;
             this.caps = caps;
+            this.sourceProvider = sourceProvider;
             this.schemaService = createSchemaService();
 
             this.dataBroker = createDataStore(schemaService);
@@ -118,7 +124,7 @@ class MdsalOperationProvider implements NetconfOperationServiceFactory {
         @Override
         public Set<NetconfOperation> getNetconfOperations() {
             TransactionProvider transactionProvider = new TransactionProvider(dataBroker, String.valueOf(currentSessionId));
-            CurrentSchemaContext currentSchemaContext = new CurrentSchemaContext(schemaService);
+            CurrentSchemaContext currentSchemaContext = new CurrentSchemaContext(schemaService, sourceProvider);
 
             ContainerNode netconf = createNetconfState();
 
index 4572c09de76bd9e1cafd4cff46cdf8adcc04434d..3233ea57a46c178723420118748659d6d2710c67 100644 (file)
@@ -102,7 +102,9 @@ public class NetconfDeviceSimulator implements Closeable {
         this.nioExecutor = nioExecutor;
     }
 
-    private NetconfServerDispatcherImpl createDispatcher(final Set<Capability> capabilities, final boolean exi, final int generateConfigsTimeout, final Optional<File> notificationsFile, final boolean mdSal, final Optional<File> initialConfigXMLFile) {
+    private NetconfServerDispatcherImpl createDispatcher(final Set<Capability> capabilities, final boolean exi, final int generateConfigsTimeout,
+                                                         final Optional<File> notificationsFile, final boolean mdSal, final Optional<File> initialConfigXMLFile,
+                                                         final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
 
         final Set<Capability> transformedCapabilities = Sets.newHashSet(Collections2.transform(capabilities, new Function<Capability, Capability>() {
             @Override
@@ -119,7 +121,7 @@ public class NetconfDeviceSimulator implements Closeable {
         final SessionIdProvider idProvider = new SessionIdProvider();
 
         final AggregatedNetconfOperationServiceFactory aggregatedNetconfOperationServiceFactory = new AggregatedNetconfOperationServiceFactory();
-        final NetconfOperationServiceFactory operationProvider = mdSal ? new MdsalOperationProvider(idProvider, transformedCapabilities, schemaContext) :
+        final NetconfOperationServiceFactory operationProvider = mdSal ? new MdsalOperationProvider(idProvider, transformedCapabilities, schemaContext, sourceProvider) :
             new SimulatedOperationProvider(idProvider, transformedCapabilities, notificationsFile, initialConfigXMLFile);
 
         transformedCapabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
@@ -147,10 +149,17 @@ public class NetconfDeviceSimulator implements Closeable {
     public List<Integer> start(final Main.Params params) {
         LOG.info("Starting {}, {} simulated devices starting on port {}", params.deviceCount, params.ssh ? "SSH" : "TCP", params.startingPort);
 
-        final Set<Capability> capabilities = parseSchemasToModuleCapabilities(params);
+        final SharedSchemaRepository schemaRepo = new SharedSchemaRepository("netconf-simulator");
+        final Set<Capability> capabilities = parseSchemasToModuleCapabilities(params, schemaRepo);
 
         final NetconfServerDispatcherImpl dispatcher = createDispatcher(capabilities, params.exi, params.generateConfigsTimeout,
-                Optional.fromNullable(params.notificationFile), params.mdSal, Optional.fromNullable(params.initialConfigXMLFile));
+                Optional.fromNullable(params.notificationFile), params.mdSal, Optional.fromNullable(params.initialConfigXMLFile),
+                new SchemaSourceProvider<YangTextSchemaSource>() {
+                    @Override
+                    public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
+                        return schemaRepo.getSchemaSource(sourceIdentifier, YangTextSchemaSource.class);
+                    }
+                });
 
         int currentPort = params.startingPort;
 
@@ -258,8 +267,7 @@ public class NetconfDeviceSimulator implements Closeable {
         }
     }
 
-    private Set<Capability> parseSchemasToModuleCapabilities(final Main.Params params) {
-        final SharedSchemaRepository consumer = new SharedSchemaRepository("netconf-simulator");
+    private Set<Capability> parseSchemasToModuleCapabilities(final Main.Params params, final SharedSchemaRepository consumer) {
         final Set<SourceIdentifier> loadedSources = Sets.newHashSet();
 
         consumer.registerSchemaSourceListener(TextToASTTransformer.create(consumer, consumer));