Fix NPE when trying to download restconf provided yang files 04/65804/5
authorTomas Cere <tomas.cere@pantheon.tech>
Tue, 21 Nov 2017 15:45:42 +0000 (16:45 +0100)
committerTomas Cere <tomas.cere@pantheon.tech>
Wed, 22 Nov 2017 13:37:34 +0000 (14:37 +0100)
Restconf throws a NPE when trying to download the provided yang files
due to using Module.getSource() which is deprecated an @Nullable.
Switch this to using DOMSchemaService.
This fixes the NPE only in the rfc8040 implementation,
draft02 still most likely has it.

Change-Id: Ic8fc94a26a1e29e037872dfdc16c97ef19fcf115
Signed-off-by: Tomas Cere <tomas.cere@pantheon.tech>
17 files changed:
restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/schema/SchemaExportContext.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/md/sal/rest/schema/SchemaExportContentYangBodyWriter.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/md/sal/rest/schema/SchemaRetrievalServiceImpl.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfProviderImpl.java
restconf/restconf-nb-bierman02/src/main/resources/org/opendaylight/blueprint/restconf-config.xml
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/RestConnectorProvider.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/schema/SchemaExportContentYangBodyWriter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/services/simple/impl/RestconfSchemaServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/services/wrapper/ServiceWrapper.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/services/wrapper/ServicesWrapperImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifier.java
restconf/restconf-nb-rfc8040/src/main/resources/org/opendaylight/blueprint/restconf-bp.xml
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/RestConnectorProviderTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040ImplTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/services/simple/impl/RestconfSchemaServiceTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifierTest.java

index 7f634e203d09c09d9dfa90cdc436eceee9613985..ac2d9c3e64895e198b43d9954eaade30762dbb0b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.restconf.common.schema;
 
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -14,10 +15,13 @@ public class SchemaExportContext {
 
     private final SchemaContext schemaContext;
     private final Module module;
+    private final DOMYangTextSourceProvider sourceProvider;
 
-    public SchemaExportContext(final SchemaContext ctx, final Module module) {
+    public SchemaExportContext(final SchemaContext ctx, final Module module,
+                               final DOMYangTextSourceProvider sourceProvider) {
         schemaContext = ctx;
         this.module = module;
+        this.sourceProvider = sourceProvider;
     }
 
     public SchemaContext getSchemaContext() {
@@ -28,4 +32,7 @@ public class SchemaExportContext {
         return module;
     }
 
+    public DOMYangTextSourceProvider getSourceProvider() {
+        return sourceProvider;
+    }
 }
index 182224fb05a4220f0fdc7f210600c7976579b1c4..4826405496ce17653e41e02f50b070e4adc177fb 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.netconf.md.sal.rest.schema;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.PrintWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import javax.ws.rs.Produces;
@@ -19,6 +18,9 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 import org.opendaylight.restconf.common.schema.SchemaExportContext;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 
 @Provider
 @Produces({ SchemaRetrievalService.YANG_MEDIA_TYPE })
@@ -41,8 +43,14 @@ public class SchemaExportContentYangBodyWriter implements MessageBodyWriter<Sche
             final Annotation[] annotations, final MediaType mediaType,
             final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
             WebApplicationException {
-        final PrintWriter writer = new PrintWriter(entityStream);
-        writer.write(context.getModule().getSource());
-
+        final RevisionSourceIdentifier sourceId = RevisionSourceIdentifier.create(context.getModule().getName(),
+                context.getModule().getQNameModule().getFormattedRevision());
+        final YangTextSchemaSource yangTextSchemaSource;
+        try {
+            yangTextSchemaSource = context.getSourceProvider().getSource(sourceId).checkedGet();
+        } catch (SchemaSourceException e) {
+            throw new WebApplicationException("Unable to retrieve source from SourceProvider.", e);
+        }
+        yangTextSchemaSource.copyTo(entityStream);
     }
 }
index bdfdec7cec2e654b2c89d6c4ea08437b6040bfce..7282d03b1a7b8b27ed48fb499ddacfbd077c9db5 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.collect.Iterables;
 import java.text.ParseException;
 import java.util.Date;
 import java.util.Iterator;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
@@ -67,16 +68,20 @@ public class SchemaRetrievalServiceImpl implements SchemaRetrievalService {
         RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Revision date must be supplied.");
         final String revisionString = componentIter.next();
-        return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString);
+        return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString,
+                salContext.getYangTextSourceProvider());
     }
 
     private static SchemaExportContext getExportUsingNameAndRevision(final SchemaContext schemaContext,
-            final String moduleName, final String revisionStr) {
+             final String moduleName, final String revisionStr,
+             final DOMYangTextSourceProvider yangTextSourceProvider) {
         try {
             final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse(revisionStr);
             final Module module = schemaContext.findModuleByName(moduleName, revision);
+
             return new SchemaExportContext(
-                    schemaContext, RestconfValidationUtils.checkNotNullDocumented(module, moduleName));
+                    schemaContext, RestconfValidationUtils.checkNotNullDocumented(module, moduleName),
+                    yangTextSourceProvider);
         } catch (final ParseException e) {
             throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
         }
index 6890b0d175092a6bb47ba73340b73bfd1c2f767b..a99495cc052b5db7a059e20e7867c970c8651db5 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizat
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
@@ -94,6 +95,7 @@ public class ControllerContext implements SchemaContextListener {
     // FIXME; these three should be final
     private volatile SchemaContext globalSchema;
     private volatile DOMMountPointService mountService;
+    private volatile DOMYangTextSourceProvider yangTextSourceProvider;
     private DataNormalizer dataNormalizer;
 
 
@@ -106,6 +108,14 @@ public class ControllerContext implements SchemaContextListener {
         this.mountService = mountService;
     }
 
+    public DOMYangTextSourceProvider getYangTextSourceProvider() {
+        return yangTextSourceProvider;
+    }
+
+    public void setYangTextSourceProvider(DOMYangTextSourceProvider yangTextSourceProvider) {
+        this.yangTextSourceProvider = yangTextSourceProvider;
+    }
+
     private ControllerContext() {
     }
 
index 614133bdd686ca38185c8aa2259743e3c0e8f23e..4afc5f8a6810716343653963f666648d5ded60e2 100644 (file)
@@ -15,6 +15,8 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.netconf.sal.rest.api.RestConnector;
 import org.opendaylight.netconf.sal.restconf.impl.jmx.Config;
 import org.opendaylight.netconf.sal.restconf.impl.jmx.Delete;
@@ -40,12 +42,13 @@ public class RestconfProviderImpl extends AbstractMXBean
     private final IpAddress websocketAddress;
     private final PortNumber websocketPort;
     private final StatisticsRestconfServiceWrapper stats = StatisticsRestconfServiceWrapper.getInstance();
+    private final DOMSchemaService domSchemaService;
     private ListenerRegistration<SchemaContextListener> listenerRegistration;
     private Thread webSocketServerThread;
 
     public RestconfProviderImpl(DOMDataBroker domDataBroker, SchemaService schemaService, DOMRpcService rpcService,
             DOMNotificationService notificationService, DOMMountPointService mountPointService,
-            IpAddress websocketAddress, PortNumber websocketPort) {
+            DOMSchemaService domSchemaService, IpAddress websocketAddress, PortNumber websocketPort) {
         super("Draft02ProviderStatistics", "restconf-connector", null);
         this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
         this.schemaService = Preconditions.checkNotNull(schemaService);
@@ -54,6 +57,7 @@ public class RestconfProviderImpl extends AbstractMXBean
         this.mountPointService = Preconditions.checkNotNull(mountPointService);
         this.websocketAddress = Preconditions.checkNotNull(websocketAddress);
         this.websocketPort = Preconditions.checkNotNull(websocketPort);
+        this.domSchemaService = Preconditions.checkNotNull(domSchemaService);
     }
 
     public void start() {
@@ -65,6 +69,10 @@ public class RestconfProviderImpl extends AbstractMXBean
 
         ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
         ControllerContext.getInstance().setMountService(mountPointService);
+        final DOMYangTextSourceProvider domSchemaServiceExtension =
+                (DOMYangTextSourceProvider) domSchemaService.getSupportedExtensions()
+                        .get(DOMYangTextSourceProvider.class);
+        ControllerContext.getInstance().setYangTextSourceProvider(domSchemaServiceExtension);
 
         this.webSocketServerThread = new Thread(WebSocketServer.createInstance(
                 new String(websocketAddress.getValue()), websocketPort.getValue()));
index 676ab128e6359bb30c962336f87f88ed20373733..51d72f74ead1b3bc65aec37e09bc6252c2cd5a34 100644 (file)
@@ -43,6 +43,7 @@
   <reference id="domNotificationService" interface="org.opendaylight.controller.md.sal.dom.api.DOMNotificationService"/>
   <reference id="domDataBroker" interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"
           ext:filter="(type=@{databroker-service-type})"/>
+  <reference id="domSchemaService" interface="org.opendaylight.mdsal.dom.api.DOMSchemaService"/>
 
   <bean id="webSocketPort" class="org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber">
     <argument value="${websocket-port}"/>
@@ -59,6 +60,7 @@
     <argument ref="domRpcService"/>
     <argument ref="domNotificationService"/>
     <argument ref="domMountPointService"/>
+    <argument ref="domSchemaService"/>
     <argument ref="webSocketAddress"/>
     <argument ref="webSocketPort"/>
   </bean>
index be7d7a878ec228444f7aa0cc447baaca522e411b..e9aeb563f55e9d33bd4677e9b68b0f17ff36513e 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
@@ -64,6 +65,7 @@ public class RestConnectorProvider<T extends ServiceWrapper> implements Restconf
     private final DOMRpcService rpcService;
     private final DOMNotificationService notificationService;
     private final DOMMountPointService mountPointService;
+    private final DOMSchemaService domSchemaService;
     private final Builder<Object> servicesProperties;
 
     private ListenerRegistration<SchemaContextListener> listenerRegistration;
@@ -73,21 +75,25 @@ public class RestConnectorProvider<T extends ServiceWrapper> implements Restconf
     // FIXME: refactor this class and its users to interact via builder pattern, where individual
     // services are injected and then the provider is created
     public RestConnectorProvider(final DOMDataBroker domDataBroker,
-            final SchemaService schemaService, final DOMRpcService rpcService,
-            final DOMNotificationService notificationService, final DOMMountPointService mountPointService) {
-        this(domDataBroker, schemaService, rpcService, notificationService, mountPointService, null);
+             final SchemaService schemaService, final DOMRpcService rpcService,
+             final DOMNotificationService notificationService, final DOMMountPointService mountPointService,
+             final DOMSchemaService domSchemaService) {
+        this(domDataBroker, schemaService, rpcService, notificationService, mountPointService, domSchemaService, null);
+
     }
 
     public RestConnectorProvider(final DOMDataBroker domDataBroker, final SchemaService schemaService,
-            final DOMRpcService rpcService,
-            final DOMNotificationService notificationService, final DOMMountPointService mountPointService,
-            final T wrapperServices) {
+                                 final DOMRpcService rpcService,
+                                 final DOMNotificationService notificationService,
+                                 final DOMMountPointService mountPointService,
+                                 final DOMSchemaService domSchemaService, final T wrapperServices) {
         this.servicesProperties = ImmutableSet.<Object>builder();
         this.wrapperServices = wrapperServices;
         this.schemaService = Preconditions.checkNotNull(schemaService);
         this.rpcService = Preconditions.checkNotNull(rpcService);
         this.notificationService = Preconditions.checkNotNull(notificationService);
         this.mountPointService = Preconditions.checkNotNull(mountPointService);
+        this.domSchemaService = Preconditions.checkNotNull(domSchemaService);
 
         RestConnectorProvider.dataBroker = Preconditions.checkNotNull(domDataBroker);
     }
@@ -116,8 +122,8 @@ public class RestConnectorProvider<T extends ServiceWrapper> implements Restconf
 
         if (wrapperServices != null) {
             wrapperServices.setHandlers(this.schemaCtxHandler, RestConnectorProvider.mountPointServiceHandler,
-                RestConnectorProvider.transactionChainHandler, brokerHandler, rpcServiceHandler,
-                notificationServiceHandler);
+                    RestConnectorProvider.transactionChainHandler, brokerHandler, rpcServiceHandler,
+                    notificationServiceHandler, domSchemaService);
         }
     }
 
index 96bc26b38f9328a82295f029ce75950e1f0e84bf..395f2362f49fe949e4b79279fd593a836995dca3 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.restconf.nb.rfc8040.jersey.providers.schema;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.PrintWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import javax.ws.rs.Produces;
@@ -20,6 +19,9 @@ import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 import org.opendaylight.restconf.common.schema.SchemaExportContext;
 import org.opendaylight.restconf.nb.rfc8040.Rfc8040;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 
 @Provider
 @Produces({ Rfc8040.MediaTypes.YANG })
@@ -42,8 +44,14 @@ public class SchemaExportContentYangBodyWriter implements MessageBodyWriter<Sche
             final Annotation[] annotations, final MediaType mediaType,
             final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
             WebApplicationException {
-        final PrintWriter writer = new PrintWriter(entityStream);
-        writer.write(context.getModule().getSource());
-
+        final RevisionSourceIdentifier sourceId = RevisionSourceIdentifier.create(context.getModule().getName(),
+                context.getModule().getQNameModule().getFormattedRevision());
+        final YangTextSchemaSource yangTextSchemaSource;
+        try {
+            yangTextSchemaSource = context.getSourceProvider().getSource(sourceId).checkedGet();
+        } catch (SchemaSourceException e) {
+            throw new WebApplicationException("Unable to retrieve source from SourceProvider.", e);
+        }
+        yangTextSchemaSource.copyTo(entityStream);
     }
 }
index 231b436c5e2e6d8400ee8701f6d91d6c8839750d..e93c66827cd9a9d45328ede5f4fed1087eb4f5d1 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.services.simple.impl;
 
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.restconf.common.schema.SchemaExportContext;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
@@ -23,6 +24,7 @@ public class RestconfSchemaServiceImpl implements RestconfSchemaService {
 
     private SchemaContextHandler schemaContextHandler;
     private DOMMountPointServiceHandler domMountPointServiceHandler;
+    private DOMYangTextSourceProvider sourceProvider;
 
     /**
      * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext}
@@ -34,16 +36,18 @@ public class RestconfSchemaServiceImpl implements RestconfSchemaService {
      *             handling dom mount point service
      */
     public RestconfSchemaServiceImpl(final SchemaContextHandler schemaContextHandler,
-            final DOMMountPointServiceHandler domMountPointServiceHandler) {
+                                     final DOMMountPointServiceHandler domMountPointServiceHandler,
+                                     final DOMYangTextSourceProvider sourceProvider) {
         this.schemaContextHandler = schemaContextHandler;
         this.domMountPointServiceHandler = domMountPointServiceHandler;
+        this.sourceProvider = sourceProvider;
     }
 
     @Override
     public SchemaExportContext getSchema(final String identifier) {
         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
         return ParserIdentifier.toSchemaExportContextFromIdentifier(schemaContextRef.get(), identifier,
-                this.domMountPointServiceHandler.get());
+                this.domMountPointServiceHandler.get(), sourceProvider);
     }
 
     @Override
@@ -53,6 +57,8 @@ public class RestconfSchemaServiceImpl implements RestconfSchemaService {
                 schemaContextHandler = (SchemaContextHandler) object;
             } else if (object instanceof DOMMountPointServiceHandler) {
                 domMountPointServiceHandler = (DOMMountPointServiceHandler) object;
+            } else if (object instanceof DOMYangTextSourceProvider) {
+                sourceProvider = (DOMYangTextSourceProvider) object;
             }
         }
     }
index ee2538d7b046f4a0a595312b1871a41f53202714..157d7d4934917ff8db3d6d2a986e4fb85365ecac 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.services.wrapper;
 
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.NotificationServiceHandler;
@@ -18,5 +19,6 @@ public interface ServiceWrapper {
 
     void setHandlers(SchemaContextHandler schemaCtxHandler, DOMMountPointServiceHandler domMountPointServiceHandler,
             TransactionChainHandler transactionChainHandler, DOMDataBrokerHandler domDataBrokerHandler,
-            RpcServiceHandler rpcServiceHandler, NotificationServiceHandler notificationServiceHandler);
+            RpcServiceHandler rpcServiceHandler, NotificationServiceHandler notificationServiceHandler,
+            DOMSchemaService domSchemaService);
 }
index 1d585c5c8b9ec37248651bfe72ab99ef40c22a87..269900231d4847b5dd6d808f2a7c11dd44cd4856 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.restconf.nb.rfc8040.services.wrapper;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.restconf.common.context.NormalizedNodeContext;
 import org.opendaylight.restconf.common.patch.PatchContext;
 import org.opendaylight.restconf.common.patch.PatchStatusContext;
@@ -139,9 +141,14 @@ public class ServicesWrapperImpl implements BaseServicesWrapper, TransactionServ
     public void setHandlers(final SchemaContextHandler schemaCtxHandler,
             final DOMMountPointServiceHandler domMountPointServiceHandler,
             final TransactionChainHandler transactionChainHandler, final DOMDataBrokerHandler domDataBrokerHandler,
-            final RpcServiceHandler rpcServiceHandler, final NotificationServiceHandler notificationServiceHandler) {
+            final RpcServiceHandler rpcServiceHandler, final NotificationServiceHandler notificationServiceHandler,
+            final DOMSchemaService domSchemaService) {
         this.delegRestOpsService = new RestconfOperationsServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
-        this.delegRestSchService = new RestconfSchemaServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
+        final DOMYangTextSourceProvider yangTextSourceProvider =
+                (DOMYangTextSourceProvider) domSchemaService.getSupportedExtensions()
+                        .get(DOMYangTextSourceProvider.class);
+        this.delegRestSchService = new RestconfSchemaServiceImpl(schemaCtxHandler, domMountPointServiceHandler,
+                yangTextSourceProvider);
         this.delegRestconfSubscrService = new RestconfStreamsSubscriptionServiceImpl(domDataBrokerHandler,
                 notificationServiceHandler, schemaCtxHandler, transactionChainHandler);
         this.delegRestconfDataService =
index 875b5d88741496dbe0934f619e185b0b8b0e9987..0df51eacd3b65b7e0371c56a6208f3e769d5bebe 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Iterator;
 import java.util.List;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
@@ -204,14 +205,16 @@ public final class ParserIdentifier {
      * @return {@link SchemaExportContext}
      */
     public static SchemaExportContext toSchemaExportContextFromIdentifier(final SchemaContext schemaContext,
-            final String identifier, final DOMMountPointService domMountPointService) {
+            final String identifier, final DOMMountPointService domMountPointService,
+            final DOMYangTextSourceProvider sourceProvider) {
         final Iterable<String> pathComponents = RestconfConstants.SLASH_SPLITTER.split(identifier);
         final Iterator<String> componentIter = pathComponents.iterator();
         if (!Iterables.contains(pathComponents, RestconfConstants.MOUNT)) {
             final String moduleName = RestconfValidation.validateAndGetModulName(componentIter);
             final Date revision = RestconfValidation.validateAndGetRevision(componentIter);
             final Module module = schemaContext.findModuleByName(moduleName, revision);
-            return new SchemaExportContext(schemaContext, module);
+
+            return new SchemaExportContext(schemaContext, module, sourceProvider);
         } else {
             final StringBuilder pathBuilder = new StringBuilder();
             while (componentIter.hasNext()) {
@@ -234,7 +237,7 @@ public final class ParserIdentifier {
             final String moduleName = RestconfValidation.validateAndGetModulName(componentIter);
             final Date revision = RestconfValidation.validateAndGetRevision(componentIter);
             final Module module = point.getMountPoint().getSchemaContext().findModuleByName(moduleName, revision);
-            return new SchemaExportContext(point.getMountPoint().getSchemaContext(), module);
+            return new SchemaExportContext(point.getMountPoint().getSchemaContext(), module, sourceProvider);
         }
     }
 }
index 6498a76aa637ee1f383d6ee1bace533379ac4fbf..ce2a39bac59794d81de895db14d767ba4928781b 100644 (file)
@@ -35,6 +35,7 @@
   <reference id="domNotificationService" interface="org.opendaylight.controller.md.sal.dom.api.DOMNotificationService"/>
   <reference id="domDataBroker" interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"
           ext:filter="(type=@{databroker-service-type})"/>
+  <reference id="domSchemaService" interface="org.opendaylight.mdsal.dom.api.DOMSchemaService"/>
 
   <bean id="wrapper" class="org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServicesWrapperImpl"
           factory-method="getInstance" />
@@ -46,6 +47,7 @@
     <argument ref="domRpcService"/>
     <argument ref="domNotificationService"/>
     <argument ref="domMountPointService"/>
+    <argument ref="domSchemaService"/>
     <argument ref="wrapper"/>
   </bean>
 
index 1fcc3e00242aa2661a312cc39bbea355ad5a9dd2..441f0f4833e70528369039818f51ef9344f07681 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServicesWrapperImpl;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -43,6 +44,8 @@ public class RestConnectorProviderTest {
     @Mock private DOMNotificationService mockNotificationService;
     @Mock DOMTransactionChain mockTransactionChain;
     @Mock private ListenerRegistration<SchemaContextListener> mockRegistration;
+    @Mock
+    private DOMSchemaService domSchemaService;
 
     @Rule
     public ExpectedException thrown = ExpectedException.none();
@@ -56,7 +59,7 @@ public class RestConnectorProviderTest {
                 Mockito.any(SchemaContextHandler.class));
 
         this.connectorProvider = new RestConnectorProvider(mockDataBroker, mockSchemaService, mockRpcService,
-                mockNotificationService, mockMountPointService, ServicesWrapperImpl.getInstance());
+                mockNotificationService, mockMountPointService, domSchemaService, ServicesWrapperImpl.getInstance());
     }
 
     /**
index 4909e0ffbb2ab49636013fd451aecdce2433d8f9..0d1647d13a94848379ff57964d6e59a5a33e8c40 100644 (file)
@@ -50,6 +50,7 @@ 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.api.DOMTransactionChain;
 import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.restconf.nb.rfc8040.TestUtils;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
@@ -135,6 +136,9 @@ public class JSONRestconfServiceRfc8040ImplTest {
     @Mock
     private DOMRpcService mockRpcService;
 
+    @Mock
+    private DOMSchemaService domSchemaService;
+
     private JSONRestconfServiceRfc8040Impl service;
 
     @BeforeClass
@@ -181,7 +185,7 @@ public class JSONRestconfServiceRfc8040ImplTest {
         ServicesWrapperImpl.getInstance().setHandlers(mockSchemaContextHandler, mountPointServiceHandler,
                 txChainHandler, new DOMDataBrokerHandler(mockDOMDataBroker),
                 new RpcServiceHandler(mockRpcService),
-                new NotificationServiceHandler(mock(DOMNotificationService.class)));
+                new NotificationServiceHandler(mock(DOMNotificationService.class)), domSchemaService);
 
         service = new JSONRestconfServiceRfc8040Impl(ServicesWrapperImpl.getInstance(), mountPointServiceHandler);
     }
index 9b74c5ec314b6c2753cebdac67933426eb83a519..d3c0a19cd94f82c3639114d7ca3eec96816c46f8 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
 import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.common.schema.SchemaExportContext;
@@ -63,6 +64,8 @@ public class RestconfSchemaServiceTest {
     private SchemaContextHandler mockContextHandler;
     @Mock
     private DOMMountPointServiceHandler mockMountPointHandler;
+    @Mock
+    private DOMYangTextSourceProvider sourceProvider;
 
     // schema context with modules
     private SchemaContext schemaContext;
@@ -106,7 +109,8 @@ public class RestconfSchemaServiceTest {
         ((DOMMountPointServiceImpl) this.mountPointService).registerMountPoint(this.mountPointWithNullSchemaContext);
         when(this.mockMountPointHandler.get()).thenReturn(this.mountPointService);
 
-        this.schemaService = new RestconfSchemaServiceImpl(this.mockContextHandler, this.mockMountPointHandler);
+        this.schemaService = new RestconfSchemaServiceImpl(this.mockContextHandler, this.mockMountPointHandler,
+                sourceProvider);
     }
 
     /**
index dd2330800eb12101f35e14459442b7d1e47308a3..ba33cd6ef0c608ff2a6ea1a5e34cf565d1574c3d 100644 (file)
@@ -27,6 +27,8 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
 import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
@@ -97,6 +99,10 @@ public class ParserIdentifierTest {
     private DOMMountPoint mockMountPoint;
     @Mock
     private DOMMountPointService mockMountPointService;
+    @Mock
+    private DOMSchemaService domSchemaService;
+    @Mock
+    private DOMYangTextSourceProvider sourceProvider;
 
     @Rule
     public final ExpectedException thrown = ExpectedException.none();
@@ -461,7 +467,7 @@ public class ParserIdentifierTest {
     @Test
     public void toSchemaExportContextFromIdentifierTest() {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
-                this.schemaContext, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null);
+                this.schemaContext, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
 
         assertNotNull("Export context should be parsed", exportContext);
 
@@ -485,7 +491,7 @@ public class ParserIdentifierTest {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
                 this.schemaContext,
                 "not-existing-module" + "/" + "2016-01-01",
-                null);
+                null, sourceProvider);
 
         assertNotNull("Export context should be parsed", exportContext);
         assertNull("Not-existing module should be null", exportContext.getModule());
@@ -500,7 +506,7 @@ public class ParserIdentifierTest {
     public void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
         try {
             ParserIdentifier.toSchemaExportContextFromIdentifier(
-                    this.schemaContext, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null);
+                    this.schemaContext, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider);
             fail("Test should fail due to invalid identifier supplied");
         } catch (final RestconfDocumentedException e) {
             assertEquals("Not expected error type",
@@ -521,7 +527,7 @@ public class ParserIdentifierTest {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
                 this.schemaContext,
                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
-                this.mountPointService);
+                this.mountPointService, sourceProvider);
 
         final Module module = exportContext.getModule();
         assertNotNull("Export context should contains test module", module);
@@ -543,7 +549,7 @@ public class ParserIdentifierTest {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
                 this.schemaContext,
                 MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
-                this.mountPointService);
+                this.mountPointService, sourceProvider);
 
         assertNotNull("Export context should be parsed", exportContext);
         assertNull("Not-existing module should be null", exportContext.getModule());
@@ -560,7 +566,7 @@ public class ParserIdentifierTest {
             ParserIdentifier.toSchemaExportContextFromIdentifier(
                     this.schemaContext,
                     MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME,
-                    this.mountPointService);
+                    this.mountPointService, sourceProvider);
 
             fail("Test should fail due to invalid identifier supplied");
         } catch (final RestconfDocumentedException e) {
@@ -580,7 +586,7 @@ public class ParserIdentifierTest {
     @Test
     public void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
         this.thrown.expect(NullPointerException.class);
-        ParserIdentifier.toSchemaExportContextFromIdentifier(this.schemaContext, null, null);
+        ParserIdentifier.toSchemaExportContextFromIdentifier(this.schemaContext, null, null, sourceProvider);
     }
 
     /**
@@ -590,7 +596,8 @@ public class ParserIdentifierTest {
     @Test
     public void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
         this.thrown.expect(NullPointerException.class);
-        ParserIdentifier.toSchemaExportContextFromIdentifier(null, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null);
+        ParserIdentifier.toSchemaExportContextFromIdentifier(null, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
+                sourceProvider);
     }
 
     /**
@@ -608,7 +615,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_NAME
                 + "/"
                 + TEST_MODULE_REVISION,
-                this.mountPointService);
+                this.mountPointService,
+                sourceProvider);
     }
 
     /**
@@ -626,7 +634,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_NAME
                 + "/"
                 + TEST_MODULE_REVISION,
-                null);
+                null,
+                sourceProvider);
     }
 
     /**
@@ -644,7 +653,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_NAME
                 + "/"
                 + TEST_MODULE_REVISION,
-                this.mockMountPointService);
+                this.mockMountPointService,
+                sourceProvider);
     }
 
     /**