Bug 6951 - Implement Query parameters - with-defaults 07/48407/2
authorJakub Toth <jatoth@cisco.com>
Wed, 16 Nov 2016 13:47:33 +0000 (14:47 +0100)
committerJakub Toth <jatoth@cisco.com>
Wed, 16 Nov 2016 15:24:32 +0000 (16:24 +0100)
  * fixed tests

Change-Id: Idae6981b7fd0df3e690965b063b7bd3975d049c5
Signed-off-by: Jakub Toth <jatoth@cisco.com>
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/api/JSONRestconfService.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BrokerFacade.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/QueryParametersParser.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/WriterParameters.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/impl/RestconfDataServiceImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/ReadDataTransactionUtil.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/RestconfDataServiceConstant.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JSONRestconfServiceImplTest.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java

index 1d08d89db520fd04d38c1de434f56f23f06a002e..d3f918741901564814cc8b176aca17ff4234df78 100644 (file)
@@ -61,7 +61,8 @@ public interface JSONRestconfService {
      * @return an Optional containing the data in JSON format if present.
      * @throws OperationFailedException if the request fails.
      */
-    Optional<String> get(String uriPath, LogicalDatastoreType datastoreType) throws OperationFailedException;
+    Optional<String> get(String uriPath, LogicalDatastoreType datastoreType, UriInfo uriInfo)
+            throws OperationFailedException;
 
     /**
      * Invokes a yang-defined RPC.
index f0fa715f0f1567beb3fee759a9b950739354517e..940932025103c1880167d5cc1bcd923f3d9e2382 100644 (file)
@@ -43,8 +43,14 @@ import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
 import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
@@ -52,11 +58,17 @@ import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
@@ -96,28 +108,89 @@ public class BrokerFacade {
         }
     }
 
-    // READ configuration
+    /**
+     * Read config data by path
+     *
+     * @param path
+     *            - path of data
+     * @return read date
+     */
     public NormalizedNode<?, ?> readConfigurationData(final YangInstanceIdentifier path) {
+        return readConfigurationData(path, null);
+    }
+
+    /**
+     * Read config data by path
+     *
+     * @param path
+     *            - path of data
+     * @param withDefa
+     *            - value of with-defaults parameter
+     * @return read date
+     */
+    public NormalizedNode<?, ?> readConfigurationData(final YangInstanceIdentifier path, final String withDefa) {
         checkPreconditions();
-        return readDataViaTransaction(this.domDataBroker.newReadOnlyTransaction(), CONFIGURATION, path);
+        return readDataViaTransaction(this.domDataBroker.newReadOnlyTransaction(), CONFIGURATION, path, withDefa);
     }
 
-    public NormalizedNode<?, ?> readConfigurationData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
+    /**
+     * Read config data from mount point by path.
+     *
+     * @param mountPoint
+     *            - mount point for reading data
+     * @param path
+     *            - path of data
+     * @return read data
+     */
+    public NormalizedNode<?, ?> readConfigurationData(final DOMMountPoint mountPoint,
+            final YangInstanceIdentifier path) {
+        return readConfigurationData(mountPoint, path, null);
+    }
+
+    /**
+     * Read config data from mount point by path.
+     *
+     * @param mountPoint
+     *            - mount point for reading data
+     * @param path
+     *            - path of data
+     * @param withDefa
+     *            - value of with-defaults parameter
+     * @return read data
+     */
+    public NormalizedNode<?, ?> readConfigurationData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path,
+            final String withDefa) {
         final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
         if (domDataBrokerService.isPresent()) {
-            return readDataViaTransaction(domDataBrokerService.get().newReadOnlyTransaction(), CONFIGURATION, path);
+            return readDataViaTransaction(domDataBrokerService.get().newReadOnlyTransaction(), CONFIGURATION, path,
+                    withDefa);
         }
         final String errMsg = "DOM data broker service isn't available for mount point " + path;
         LOG.warn(errMsg);
         throw new RestconfDocumentedException(errMsg);
     }
 
-    // READ operational
+    /**
+     * Read operational data by path.
+     *
+     * @param path
+     *            - path of data
+     * @return read data
+     */
     public NormalizedNode<?, ?> readOperationalData(final YangInstanceIdentifier path) {
         checkPreconditions();
         return readDataViaTransaction(this.domDataBroker.newReadOnlyTransaction(), OPERATIONAL, path);
     }
 
+    /**
+     * Read operational data from mount point by path.
+     *
+     * @param mountPoint
+     *            - mount point for reading data
+     * @param path
+     *            - path of data
+     * @return read data
+     */
     public NormalizedNode<?, ?> readOperationalData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
         final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
         if (domDataBrokerService.isPresent()) {
@@ -440,6 +513,11 @@ public class BrokerFacade {
 
     private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
             final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
+        return readDataViaTransaction(transaction, datastore, path, null);
+    }
+
+    private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
+            final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final String withDefa) {
         LOG.trace("Read {} via Restconf: {}", datastore.name(), path);
         final ListenableFuture<Optional<NormalizedNode<?, ?>>> listenableFuture = transaction.read(datastore, path);
         final ReadDataResult<NormalizedNode<?, ?>> readData = new ReadDataResult<>();
@@ -467,7 +545,135 @@ public class BrokerFacade {
             LOG.warn(msg);
             throw new RestconfDocumentedException(msg, e);
         }
-        return readData.getResult();
+        if (withDefa == null) {
+            return readData.getResult();
+        } else {
+            return prepareDataByParamWithDef(readData.getResult(), path, withDefa);
+        }
+
+    }
+
+    private NormalizedNode<?, ?> prepareDataByParamWithDef(final NormalizedNode<?, ?> result,
+            final YangInstanceIdentifier path, final String withDefa) {
+        boolean trim;
+        switch (withDefa) {
+            case "trim":
+                trim = true;
+                break;
+            case "explicit":
+                trim = false;
+                break;
+            default:
+                throw new RestconfDocumentedException("Bad value used with with-defaults parameter : " + withDefa);
+        }
+
+        final SchemaContext ctx = ControllerContext.getInstance().getGlobalSchema();
+        final DataSchemaContextTree baseSchemaCtxTree = DataSchemaContextTree.from(ctx);
+        final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+        if (result instanceof ContainerNode) {
+            final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
+                    Builders.containerBuilder((ContainerSchemaNode) baseSchemaNode);
+            buildCont(builder, (ContainerNode) result, baseSchemaCtxTree, path, trim);
+            return builder.build();
+        } else {
+            final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
+                    Builders.mapEntryBuilder((ListSchemaNode) baseSchemaNode);
+            buildMapEntryBuilder(builder, (MapEntryNode) result, baseSchemaCtxTree, path, trim,
+                    ((ListSchemaNode) baseSchemaNode).getKeyDefinition());
+            return builder.build();
+        }
+    }
+
+    private void buildMapEntryBuilder(final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder,
+            final MapEntryNode result, final DataSchemaContextTree baseSchemaCtxTree,
+            final YangInstanceIdentifier actualPath, final boolean trim, final List<QName> keys) {
+        for (final DataContainerChild<? extends PathArgument, ?> child : result.getValue()) {
+            final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
+            final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+            if (child instanceof ContainerNode) {
+                final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> childBuilder =
+                        Builders.containerBuilder((ContainerSchemaNode) childSchema);
+                buildCont(childBuilder, (ContainerNode) child, baseSchemaCtxTree, path, trim);
+                builder.withChild(childBuilder.build());
+            } else if (child instanceof MapNode) {
+                final CollectionNodeBuilder<MapEntryNode, MapNode> childBuilder =
+                        Builders.mapBuilder((ListSchemaNode) childSchema);
+                buildList(childBuilder, (MapNode) child, baseSchemaCtxTree, path, trim,
+                        ((ListSchemaNode) childSchema).getKeyDefinition());
+                builder.withChild(childBuilder.build());
+            } else if (child instanceof LeafNode) {
+                final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
+                final String nodeVal = ((LeafNode<String>) child).getValue();
+                final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                        Builders.leafBuilder((LeafSchemaNode) childSchema);
+                if (keys.contains(child.getNodeType())) {
+                    leafBuilder.withValue(((LeafNode) child).getValue());
+                    builder.withChild(leafBuilder.build());
+                } else {
+                    if (trim) {
+                        if ((defaultVal == null) || !defaultVal.equals(nodeVal)) {
+                            leafBuilder.withValue(((LeafNode) child).getValue());
+                            builder.withChild(leafBuilder.build());
+                        }
+                    } else {
+                        if ((defaultVal != null) && defaultVal.equals(nodeVal)) {
+                            leafBuilder.withValue(((LeafNode) child).getValue());
+                            builder.withChild(leafBuilder.build());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void buildList(final CollectionNodeBuilder<MapEntryNode, MapNode> builder, final MapNode result,
+            final DataSchemaContextTree baseSchemaCtxTree, final YangInstanceIdentifier path, final boolean trim,
+            final List<QName> keys) {
+        for (final MapEntryNode mapEntryNode : result.getValue()) {
+            final YangInstanceIdentifier actualNode = path.node(mapEntryNode.getIdentifier());
+            final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(actualNode).getDataSchemaNode();
+            final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
+                    Builders.mapEntryBuilder((ListSchemaNode) childSchema);
+            buildMapEntryBuilder(mapEntryBuilder, mapEntryNode, baseSchemaCtxTree, actualNode, trim, keys);
+            builder.withChild(mapEntryBuilder.build());
+        }
+    }
+
+    private void buildCont(final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder,
+            final ContainerNode result, final DataSchemaContextTree baseSchemaCtxTree,
+            final YangInstanceIdentifier actualPath, final boolean trim) {
+        for (final DataContainerChild<? extends PathArgument, ?> child : result.getValue()) {
+            final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
+            final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+            if(child instanceof ContainerNode){
+                final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builderChild =
+                        Builders.containerBuilder((ContainerSchemaNode) childSchema);
+                buildCont(builderChild, result, baseSchemaCtxTree, actualPath, trim);
+                builder.withChild(builderChild.build());
+            } else if (child instanceof MapNode) {
+                final CollectionNodeBuilder<MapEntryNode, MapNode> childBuilder =
+                        Builders.mapBuilder((ListSchemaNode) childSchema);
+                buildList(childBuilder, (MapNode) child, baseSchemaCtxTree, path, trim,
+                        ((ListSchemaNode) childSchema).getKeyDefinition());
+                builder.withChild(childBuilder.build());
+            } else if (child instanceof LeafNode) {
+                final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
+                final String nodeVal = ((LeafNode<String>) child).getValue();
+                final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                        Builders.leafBuilder((LeafSchemaNode) childSchema);
+                if (trim) {
+                    if ((defaultVal == null) || !defaultVal.equals(nodeVal)) {
+                        leafBuilder.withValue(((LeafNode) child).getValue());
+                        builder.withChild(leafBuilder.build());
+                    }
+                } else {
+                    if ((defaultVal != null) && defaultVal.equals(nodeVal)) {
+                        leafBuilder.withValue(((LeafNode) child).getValue());
+                        builder.withChild(leafBuilder.build());
+                    }
+                }
+            }
+        }
     }
 
     /**
index 57457519f6717818d05fc286d22c86e896f18298..9c9084fc2f2cfb4cbbdd8f5b314e4b53f7c16a95 100644 (file)
@@ -92,15 +92,16 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab
     }
 
     @Override
-    public Optional<String> get(final String uriPath, final LogicalDatastoreType datastoreType) throws OperationFailedException {
+    public Optional<String> get(final String uriPath, final LogicalDatastoreType datastoreType, final UriInfo uriInfo)
+            throws OperationFailedException {
         LOG.debug("get: uriPath: {}", uriPath);
 
         try {
             NormalizedNodeContext readData;
             if(datastoreType == LogicalDatastoreType.CONFIGURATION) {
-                readData = RestconfImpl.getInstance().readConfigurationData(uriPath, null);
+                readData = RestconfImpl.getInstance().readConfigurationData(uriPath, uriInfo);
             } else {
-                readData = RestconfImpl.getInstance().readOperationalData(uriPath, null);
+                readData = RestconfImpl.getInstance().readOperationalData(uriPath, uriInfo);
             }
 
             final Optional<String> result = Optional.of(toJson(readData));
index 082ba18e81e183b4db3d40c80b83fddd2e7a58f2..70d9280c4207c09c2cb7857cd8cfe319bb98d1c5 100644 (file)
@@ -24,12 +24,17 @@ public class QueryParametersParser {
 
         @Override
         public String toString() {
-            return uriParameterName;
+            return this.uriParameterName;
         }
     }
 
     public static WriterParameters parseWriterParameters(final UriInfo info) {
-        WriterParameters.WriterParametersBuilder wpBuilder = new WriterParameters.WriterParametersBuilder();
+        return parseParams(info, false);
+    }
+
+    private static WriterParameters parseParams(final UriInfo info, final boolean tagged) {
+        final WriterParameters.WriterParametersBuilder wpBuilder = new WriterParameters.WriterParametersBuilder();
+        wpBuilder.setTagged(tagged);
         if(info == null) {
             return wpBuilder.build();
         }
@@ -55,4 +60,8 @@ public class QueryParametersParser {
         return wpBuilder.build();
     }
 
+    public static WriterParameters parseWriterParameters(final UriInfo uriInfo, final boolean tagged) {
+        return parseParams(uriInfo, tagged);
+    }
+
 }
index 2f724ec26a95dae3344ef3568990417885a80101..637d345dc79c5e1d074e3eb174ae4d291e8032c8 100644 (file)
@@ -674,21 +674,48 @@ public class RestconfImpl implements RestconfService {
 
     @Override
     public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
+        boolean withDefa_used = false;
+        String withDefa = null;
+
+        for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
+            switch (entry.getKey()) {
+                case "with-defaults":
+                    if (!withDefa_used) {
+                        withDefa_used = true;
+                        withDefa = entry.getValue().iterator().next();
+                    } else {
+                        throw new RestconfDocumentedException("With-defaults parameter can be used only once.");
+                    }
+                    break;
+            }
+        }
+        boolean tagged = false;
+        if (withDefa_used) {
+            if (withDefa.equals("report-all-tagged")) {
+                tagged = true;
+                withDefa = null;
+            }
+            if (withDefa.equals("report-all")) {
+                withDefa = null;
+            }
+        }
+
         final InstanceIdentifierContext<?> iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
         final DOMMountPoint mountPoint = iiWithData.getMountPoint();
         NormalizedNode<?, ?> data = null;
         final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
         if (mountPoint != null) {
-            data = this.broker.readConfigurationData(mountPoint, normalizedII);
+            data = this.broker.readConfigurationData(mountPoint, normalizedII, withDefa);
         } else {
-            data = this.broker.readConfigurationData(normalizedII);
+            data = this.broker.readConfigurationData(normalizedII, withDefa);
         }
         if(data == null) {
             final String errMsg = "Request could not be completed because the relevant data model content does not exist ";
             LOG.debug(errMsg + identifier);
             throw new RestconfDocumentedException(errMsg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
         }
-        return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseWriterParameters(uriInfo));
+        return new NormalizedNodeContext(iiWithData, data,
+                QueryParametersParser.parseWriterParameters(uriInfo, tagged));
     }
 
     @Override
@@ -739,7 +766,7 @@ public class RestconfImpl implements RestconfService {
                 default:
                     throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
             }
-        }
+            }
 
         if (point_used && !insert_used) {
             throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
index 996f6d9d0d5e63bbd88d22d9f498c18e3cae339c..9d576c466f0c5f1a6a19c22e06f0804195b0046d 100644 (file)
@@ -17,28 +17,34 @@ public class WriterParameters {
     private final Integer depth;
     private final List<Set<QName>> fields;
     private final boolean prettyPrint;
+    private final boolean tagged;
 
     private WriterParameters(final WriterParametersBuilder builder) {
         this.content = builder.content;
         this.depth = builder.depth;
         this.fields = builder.fields;
         this.prettyPrint = builder.prettyPrint;
+        this.tagged = builder.tagged;
     }
 
     public String getContent() {
-        return content;
+        return this.content;
     }
 
     public Integer getDepth() {
-        return depth;
+        return this.depth;
     }
 
     public List<Set<QName>> getFields() {
-        return fields;
+        return this.fields;
     }
 
     public boolean isPrettyPrint() {
-        return prettyPrint;
+        return this.prettyPrint;
+    }
+
+    public boolean isTagged() {
+        return this.tagged;
     }
 
     public static class WriterParametersBuilder {
@@ -46,6 +52,7 @@ public class WriterParameters {
         private Integer depth;
         private List<Set<QName>> fields;
         private boolean prettyPrint;
+        private boolean tagged;
 
         public WriterParametersBuilder() {}
 
@@ -72,5 +79,9 @@ public class WriterParameters {
         public WriterParameters build() {
             return new WriterParameters(this);
         }
+
+        public void setTagged(final boolean tagged) {
+            this.tagged = tagged;
+        }
     }
 }
index bb42fbb9d55cf60e2c7a47cebe057a742c16f776..a4d63a23ed060a1c5a87b9f5e23478d219ec8c33 100644 (file)
@@ -76,8 +76,34 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
                 identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
 
+        boolean withDefa_used = false;
+        String withDefa = null;
+
+        for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
+            switch (entry.getKey()) {
+                case "with-defaults":
+                    if (!withDefa_used) {
+                        withDefa_used = true;
+                        withDefa = entry.getValue().iterator().next();
+                    } else {
+                        throw new RestconfDocumentedException("With-defaults parameter can be used only once.");
+                    }
+                    break;
+            }
+        }
+        boolean tagged = false;
+        if (withDefa_used) {
+            if (withDefa.equals("report-all-tagged")) {
+                tagged = true;
+                withDefa = null;
+            }
+            if (withDefa.equals("report-all")) {
+                withDefa = null;
+            }
+        }
+
         final WriterParameters parameters = ReadDataTransactionUtil.parseUriParameters(
-                instanceIdentifier, uriInfo);
+                instanceIdentifier, uriInfo, tagged);
 
         final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
         final DOMTransactionChain transactionChain;
@@ -89,7 +115,8 @@ public class RestconfDataServiceImpl implements RestconfDataService {
 
         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
                 instanceIdentifier, mountPoint, transactionChain);
-        final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(parameters.getContent(), transactionNode);
+        final NormalizedNode<?, ?> node =
+                ReadDataTransactionUtil.readData(parameters.getContent(), transactionNode, withDefa);
         if (node == null) {
             throw new RestconfDocumentedException(
                     "Request could not be completed because the relevant data model content does not exist",
index e18ea0961337881ae5a7b32d913df1b5c7954728..56cb54627821fdf4d1aafffb0d69a57652dfc7c7 100644 (file)
@@ -21,6 +21,7 @@ import javax.annotation.Nullable;
 import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
@@ -28,7 +29,9 @@ import org.opendaylight.netconf.sal.restconf.impl.WriterParameters;
 import org.opendaylight.netconf.sal.restconf.impl.WriterParameters.WriterParametersBuilder;
 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
 import org.opendaylight.restconf.utils.parser.ParserFieldsParameter;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -36,6 +39,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
@@ -45,8 +49,15 @@ import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * Util class for read data from data store via transaction.
@@ -63,6 +74,23 @@ public final class ReadDataTransactionUtil {
         throw new UnsupportedOperationException("Util class.");
     }
 
+    /**
+     * Parse parameters from URI request and check their types and values.
+     *
+     *
+     * @param identifier
+     *            - {@link InstanceIdentifierContext}
+     * @param uriInfo
+     *            - URI info
+     * @param tagged
+     *            - set tagged for {@link WriterParameters}
+     * @return {@link WriterParameters}
+     */
+    public static @Nonnull WriterParameters parseUriParameters(@Nonnull final InstanceIdentifierContext<?> identifier,
+            @Nullable final UriInfo uriInfo, final boolean tagged) {
+        return parseParams(identifier, uriInfo, tagged);
+    }
+
     /**
      * Parse parameters from URI request and check their types and values.
      *
@@ -75,7 +103,13 @@ public final class ReadDataTransactionUtil {
      */
     public static @Nonnull WriterParameters parseUriParameters(@Nonnull final InstanceIdentifierContext<?> identifier,
                                                                @Nullable final UriInfo uriInfo) {
+        return parseParams(identifier, uriInfo, false);
+    }
+
+    private static WriterParameters parseParams(final InstanceIdentifierContext<?> identifier, final UriInfo uriInfo,
+            final boolean tagged) {
         final WriterParametersBuilder builder = new WriterParametersBuilder();
+        builder.setTagged(tagged);
 
         if (uriInfo == null) {
             return builder.build();
@@ -87,7 +121,7 @@ public final class ReadDataTransactionUtil {
                 uriInfo.getQueryParameters().keySet(),
                 RestconfDataServiceConstant.ReadData.CONTENT,
                 RestconfDataServiceConstant.ReadData.DEPTH,
-                RestconfDataServiceConstant.ReadData.FIELDS);
+                RestconfDataServiceConstant.ReadData.FIELDS, RestconfDataServiceConstant.ReadData.WITH_DEFAULTS);
 
         // read parameters from URI or set default values
         final List<String> content = uriInfo.getQueryParameters().getOrDefault(
@@ -124,9 +158,9 @@ public final class ReadDataTransactionUtil {
         if (!depth.get(0).equals(RestconfDataServiceConstant.ReadData.UNBOUNDED)) {
             final Integer value = Ints.tryParse(depth.get(0));
 
-            if (value == null
-                    || (!(value >= RestconfDataServiceConstant.ReadData.MIN_DEPTH
-                        && value <= RestconfDataServiceConstant.ReadData.MAX_DEPTH))) {
+            if ((value == null)
+                    || (!((value >= RestconfDataServiceConstant.ReadData.MIN_DEPTH)
+                        && (value <= RestconfDataServiceConstant.ReadData.MAX_DEPTH)))) {
                 throw new RestconfDocumentedException(
                         new RestconfError(RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.INVALID_VALUE,
                                 "Invalid depth parameter: " + depth, null,
@@ -154,18 +188,38 @@ public final class ReadDataTransactionUtil {
      * @return {@link NormalizedNode}
      */
     public static @Nullable NormalizedNode<?, ?> readData(@Nonnull final String valueOfContent,
-                                                          @Nonnull final TransactionVarsWrapper transactionNode) {
+            @Nonnull final TransactionVarsWrapper transactionNode) {
+        return readData(valueOfContent, transactionNode, null);
+    }
+
+    /**
+     * Read specific type of data from data store via transaction.
+     *
+     * @param valueOfContent
+     *            - type of data to read (config, state, all)
+     * @param transactionNode
+     *            - {@link TransactionVarsWrapper} - wrapper for variables
+     * @param withDefa
+     *            - vaule of with-defaults parameter
+     * @return {@link NormalizedNode}
+     */
+    public static @Nullable NormalizedNode<?, ?> readData(@Nonnull final String valueOfContent,
+            @Nonnull final TransactionVarsWrapper transactionNode, final String withDefa) {
         switch (valueOfContent) {
             case RestconfDataServiceConstant.ReadData.CONFIG:
                 transactionNode.setLogicalDatastoreType(LogicalDatastoreType.CONFIGURATION);
-                return readDataViaTransaction(transactionNode);
-
+                if (withDefa == null) {
+                    return readDataViaTransaction(transactionNode);
+                } else {
+                    return prepareDataByParamWithDef(readDataViaTransaction(transactionNode),
+                            transactionNode.getInstanceIdentifier().getInstanceIdentifier(), withDefa);
+                }
             case RestconfDataServiceConstant.ReadData.NONCONFIG:
                 transactionNode.setLogicalDatastoreType(LogicalDatastoreType.OPERATIONAL);
                 return readDataViaTransaction(transactionNode);
 
             case RestconfDataServiceConstant.ReadData.ALL:
-                return readAllData(transactionNode);
+                return readAllData(transactionNode, withDefa);
 
             default:
                 throw new RestconfDocumentedException(
@@ -175,6 +229,130 @@ public final class ReadDataTransactionUtil {
         }
     }
 
+    private static NormalizedNode<?, ?> prepareDataByParamWithDef(final NormalizedNode<?, ?> result,
+            final YangInstanceIdentifier path, final String withDefa) {
+        boolean trim;
+        switch (withDefa) {
+            case "trim":
+                trim = true;
+                break;
+            case "explicit":
+                trim = false;
+                break;
+            default:
+                throw new RestconfDocumentedException("");
+        }
+
+        final SchemaContext ctx = ControllerContext.getInstance().getGlobalSchema();
+        final DataSchemaContextTree baseSchemaCtxTree = DataSchemaContextTree.from(ctx);
+        final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+        if (result instanceof ContainerNode) {
+            final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
+                    Builders.containerBuilder((ContainerSchemaNode) baseSchemaNode);
+            buildCont(builder, (ContainerNode) result, baseSchemaCtxTree, path, trim);
+            return builder.build();
+        } else {
+            final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
+                    Builders.mapEntryBuilder((ListSchemaNode) baseSchemaNode);
+            buildMapEntryBuilder(builder, (MapEntryNode) result, baseSchemaCtxTree, path, trim,
+                    ((ListSchemaNode) baseSchemaNode).getKeyDefinition());
+            return builder.build();
+        }
+    }
+
+    private static void buildMapEntryBuilder(
+            final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder,
+            final MapEntryNode result, final DataSchemaContextTree baseSchemaCtxTree,
+            final YangInstanceIdentifier actualPath, final boolean trim, final List<QName> keys) {
+        for (final DataContainerChild<? extends PathArgument, ?> child : result.getValue()) {
+            final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
+            final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+            if (child instanceof ContainerNode) {
+                final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> childBuilder =
+                        Builders.containerBuilder((ContainerSchemaNode) childSchema);
+                buildCont(childBuilder, (ContainerNode) child, baseSchemaCtxTree, path, trim);
+                builder.withChild(childBuilder.build());
+            } else if (child instanceof MapNode) {
+                final CollectionNodeBuilder<MapEntryNode, MapNode> childBuilder =
+                        Builders.mapBuilder((ListSchemaNode) childSchema);
+                buildList(childBuilder, (MapNode) child, baseSchemaCtxTree, path, trim,
+                        ((ListSchemaNode) childSchema).getKeyDefinition());
+                builder.withChild(childBuilder.build());
+            } else if (child instanceof LeafNode) {
+                final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
+                final String nodeVal = ((LeafNode<String>) child).getValue();
+                final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                        Builders.leafBuilder((LeafSchemaNode) childSchema);
+                if (keys.contains(child.getNodeType())) {
+                    leafBuilder.withValue(((LeafNode) child).getValue());
+                    builder.withChild(leafBuilder.build());
+                } else {
+                    if (trim) {
+                        if ((defaultVal == null) || !defaultVal.equals(nodeVal)) {
+                            leafBuilder.withValue(((LeafNode) child).getValue());
+                            builder.withChild(leafBuilder.build());
+                        }
+                    } else {
+                        if ((defaultVal != null) && defaultVal.equals(nodeVal)) {
+                            leafBuilder.withValue(((LeafNode) child).getValue());
+                            builder.withChild(leafBuilder.build());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static void buildList(final CollectionNodeBuilder<MapEntryNode, MapNode> builder, final MapNode result,
+            final DataSchemaContextTree baseSchemaCtxTree, final YangInstanceIdentifier path, final boolean trim,
+            final List<QName> keys) {
+        for (final MapEntryNode mapEntryNode : result.getValue()) {
+            final YangInstanceIdentifier actualNode = path.node(mapEntryNode.getIdentifier());
+            final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(actualNode).getDataSchemaNode();
+            final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
+                    Builders.mapEntryBuilder((ListSchemaNode) childSchema);
+            buildMapEntryBuilder(mapEntryBuilder, mapEntryNode, baseSchemaCtxTree, actualNode, trim, keys);
+            builder.withChild(mapEntryBuilder.build());
+        }
+    }
+
+    private static void buildCont(final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder,
+            final ContainerNode result, final DataSchemaContextTree baseSchemaCtxTree,
+            final YangInstanceIdentifier actualPath, final boolean trim) {
+        for (final DataContainerChild<? extends PathArgument, ?> child : result.getValue()) {
+            final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
+            final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+            if (child instanceof ContainerNode) {
+                final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builderChild =
+                        Builders.containerBuilder((ContainerSchemaNode) childSchema);
+                buildCont(builderChild, result, baseSchemaCtxTree, actualPath, trim);
+                builder.withChild(builderChild.build());
+            } else if (child instanceof MapNode) {
+                final CollectionNodeBuilder<MapEntryNode, MapNode> childBuilder =
+                        Builders.mapBuilder((ListSchemaNode) childSchema);
+                buildList(childBuilder, (MapNode) child, baseSchemaCtxTree, path, trim,
+                        ((ListSchemaNode) childSchema).getKeyDefinition());
+                builder.withChild(childBuilder.build());
+            } else if (child instanceof LeafNode) {
+                final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
+                final String nodeVal = ((LeafNode<String>) child).getValue();
+                final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                        Builders.leafBuilder((LeafSchemaNode) childSchema);
+                if (trim) {
+                    if ((defaultVal == null) || !defaultVal.equals(nodeVal)) {
+                        leafBuilder.withValue(((LeafNode) child).getValue());
+                        builder.withChild(leafBuilder.build());
+                    }
+                } else {
+                    if ((defaultVal != null) && defaultVal.equals(nodeVal)) {
+                        leafBuilder.withValue(((LeafNode) child).getValue());
+                        builder.withChild(leafBuilder.build());
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * If is set specific {@link LogicalDatastoreType} in
      * {@link TransactionVarsWrapper}, then read this type of data from DS. If
@@ -200,16 +378,24 @@ public final class ReadDataTransactionUtil {
      *
      * @param transactionNode
      *            - {@link TransactionVarsWrapper} - wrapper for variables
+     * @param withDefa
      * @return {@link NormalizedNode}
      */
-    private static @Nullable NormalizedNode<?, ?> readAllData(@Nonnull final TransactionVarsWrapper transactionNode) {
+    private static @Nullable NormalizedNode<?, ?> readAllData(@Nonnull final TransactionVarsWrapper transactionNode,
+            final String withDefa) {
         // PREPARE STATE DATA NODE
         transactionNode.setLogicalDatastoreType(LogicalDatastoreType.OPERATIONAL);
         final NormalizedNode<?, ?> stateDataNode = readDataViaTransaction(transactionNode);
 
         // PREPARE CONFIG DATA NODE
         transactionNode.setLogicalDatastoreType(LogicalDatastoreType.CONFIGURATION);
-        final NormalizedNode<?, ?> configDataNode = readDataViaTransaction(transactionNode);
+        final NormalizedNode<?, ?> configDataNode;
+        if (withDefa == null) {
+            configDataNode = readDataViaTransaction(transactionNode);
+        } else {
+            configDataNode = prepareDataByParamWithDef(readDataViaTransaction(transactionNode),
+                    transactionNode.getInstanceIdentifier().getInstanceIdentifier(), withDefa);
+        }
 
         // if no data exists
         if ((stateDataNode == null) && (configDataNode == null)) {
index e8d1b327910e598a9f25a37d8e0ed850b048a831..a2ef70b9a854010a40a16fba46c9e65070cc2e87 100644 (file)
@@ -58,6 +58,7 @@ public final class RestconfDataServiceConstant {
         public static final int MAX_DEPTH = 65535;
 
         public static final String READ_TYPE_TX = "READ";
+        public static final String WITH_DEFAULTS = "with-defaults";
 
         private ReadData() {
             throw new UnsupportedOperationException("Util class.");
index 49ddf217b340b708a10933b37e8c1a0e082f48ee..6729ea1b01286d69008f7f292708bddf9148e4fa 100644 (file)
@@ -346,16 +346,24 @@ public class JSONRestconfServiceImplTest {
 
     @Test
     public void testGetWithNoData() throws OperationFailedException {
-        doReturn(null).when(brokerFacade).readConfigurationData(notNull(YangInstanceIdentifier.class));
+        doReturn(null).when(brokerFacade).readConfigurationData(notNull(YangInstanceIdentifier.class),
+                Mockito.anyString());
         final String uriPath = "ietf-interfaces:interfaces";
-        this.service.get(uriPath, LogicalDatastoreType.CONFIGURATION);
+        final UriInfo uriInfo = Mockito.mock(UriInfo.class);
+        final MultivaluedMap<String, String> value = Mockito.mock(MultivaluedMap.class);
+        Mockito.when(value.entrySet()).thenReturn(new HashSet<>());
+        Mockito.when(uriInfo.getQueryParameters()).thenReturn(value);
+        this.service.get(uriPath, LogicalDatastoreType.CONFIGURATION, uriInfo);
     }
 
     @Test(expected=OperationFailedException.class)
     public void testGetFailure() throws Exception {
         final String invalidUriPath = "/ietf-interfaces:interfaces/invalid";
-
-        this.service.get(invalidUriPath, LogicalDatastoreType.CONFIGURATION);
+        final UriInfo uriInfo = Mockito.mock(UriInfo.class);
+        final MultivaluedMap<String, String> value = Mockito.mock(MultivaluedMap.class);
+        Mockito.when(value.entrySet()).thenReturn(new HashSet<>());
+        Mockito.when(uriInfo.getQueryParameters()).thenReturn(value);
+        this.service.get(invalidUriPath, LogicalDatastoreType.CONFIGURATION, uriInfo);
     }
 
     @SuppressWarnings("rawtypes")
@@ -443,14 +451,21 @@ public class JSONRestconfServiceImplTest {
                 .build();
 
         if(datastoreType == LogicalDatastoreType.CONFIGURATION) {
-            doReturn(entryNode).when(brokerFacade).readConfigurationData(notNull(YangInstanceIdentifier.class));
+            doReturn(entryNode).when(brokerFacade).readConfigurationData(notNull(YangInstanceIdentifier.class),
+                    Mockito.anyString());
         } else {
             doReturn(entryNode).when(brokerFacade).readOperationalData(notNull(YangInstanceIdentifier.class));
         }
 
         final String uriPath = "/ietf-interfaces:interfaces/interface/eth0";
+        final UriInfo uriInfo = Mockito.mock(UriInfo.class);
+        final MultivaluedMap<String, String> value = Mockito.mock(MultivaluedMap.class);
+        Mockito.when(value.entrySet()).thenReturn(new HashSet<>());
+        Mockito.when(uriInfo.getQueryParameters()).thenReturn(value);
+        Mockito.when(uriInfo.getQueryParameters(false)).thenReturn(value);
+        Mockito.when(value.getFirst("depth")).thenReturn("");
 
-        final Optional<String> optionalResp = this.service.get(uriPath, datastoreType);
+        final Optional<String> optionalResp = this.service.get(uriPath, datastoreType, uriInfo);
         assertEquals("Response present", true, optionalResp.isPresent());
         final String jsonResp = optionalResp.get();
 
@@ -462,7 +477,7 @@ public class JSONRestconfServiceImplTest {
 
         final ArgumentCaptor<YangInstanceIdentifier> capturedPath = ArgumentCaptor.forClass(YangInstanceIdentifier.class);
         if (datastoreType == LogicalDatastoreType.CONFIGURATION) {
-            verify(brokerFacade).readConfigurationData(capturedPath.capture());
+            verify(brokerFacade).readConfigurationData(capturedPath.capture(), Mockito.anyString());
         } else {
             verify(brokerFacade).readOperationalData(capturedPath.capture());
         }
index d5fd89777b0157641fe2abf2637a44e6504ac6ec..1bcfa8fae05d269363f3604bfb8903513ac4c593 100644 (file)
@@ -46,6 +46,7 @@ import org.glassfish.jersey.test.JerseyTest;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
@@ -172,7 +173,8 @@ public class RestGetOperationTest extends JerseyTest {
     @SuppressWarnings("unchecked")
     @Test
     public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException, ParseException {
-        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class))).thenReturn(
+        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
+                Mockito.anyString())).thenReturn(
                 prepareCnDataForMountPointTest(false));
         final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
@@ -202,8 +204,8 @@ public class RestGetOperationTest extends JerseyTest {
     @Test
     public void getDataWithSlashesBehindMountPoint() throws Exception {
         final YangInstanceIdentifier awaitedInstanceIdentifier = prepareInstanceIdentifierForList();
-        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), eq(awaitedInstanceIdentifier))).thenReturn(
-                prepareCnDataForSlashesBehindMountPointTest());
+        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), eq(awaitedInstanceIdentifier),
+                Mockito.anyString())).thenReturn(prepareCnDataForSlashesBehindMountPointTest());
         final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
         final DOMMountPointService mockMountService = mock(DOMMountPointService.class);
@@ -238,7 +240,8 @@ public class RestGetOperationTest extends JerseyTest {
     @Test
     public void getDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException,
             ParseException {
-        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class))).thenReturn(
+        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
+                Mockito.anyString())).thenReturn(
                 prepareCnDataForMountPointTest(true));
         final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
@@ -270,7 +273,7 @@ public class RestGetOperationTest extends JerseyTest {
                         .withChild(ImmutableNodes.leafNode(newTestModuleQName("type"), newTestModuleQName("test-identity")))
                         .withChild(ImmutableNodes.leafNode(newTestModuleQName("name"), "foo"))
                         .withChild(ImmutableNodes.leafNode(newTestModuleQName("data"), "bar")).build()).build();
-        when(brokerFacade.readConfigurationData(iid)).thenReturn(data);
+        when(brokerFacade.readConfigurationData(iid, null)).thenReturn(data);
 
         final String uri = "/config/test-module:modules/module/test-module:test-identity/foo";
         assertEquals(200, get(uri, MediaType.APPLICATION_XML));
@@ -670,7 +673,8 @@ public class RestGetOperationTest extends JerseyTest {
 
     @SuppressWarnings("unchecked")
     private void mockReadConfigurationDataMethod() {
-        when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(answerFromGet);
+        when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class), Mockito.anyString()))
+                .thenReturn(answerFromGet);
     }
 
     @SuppressWarnings("rawtypes")