Remove SchemaNode#getPath usage from RestconfDocumentedExceptionMapper
[netconf.git] / restconf / restconf-nb-bierman02 / src / main / java / org / opendaylight / netconf / sal / rest / impl / RestconfDocumentedExceptionMapper.java
index 9370aaebb236383971a71f87221a6353c3c2792f..b6ad9da112494781a3672b6217242ea4b7aada75 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.netconf.sal.rest.impl;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.Objects.requireNonNull;
+import static org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule.ERRORS_CONTAINER_QNAME;
 
 import com.google.common.collect.Iterables;
 import com.google.gson.stream.JsonWriter;
@@ -19,6 +20,7 @@ import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
@@ -31,7 +33,7 @@ import javax.xml.stream.FactoryConfigurationError;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
+import org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule;
 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
 import org.opendaylight.restconf.common.ErrorTags;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
@@ -39,8 +41,11 @@ import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.XMLNamespace;
+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;
+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.MapEntryNode;
@@ -64,6 +69,7 @@ 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;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -80,6 +86,11 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
 
     private static final XMLOutputFactory XML_FACTORY;
 
+    private static final YangInstanceIdentifier ERRORS = YangInstanceIdentifier.builder()
+            .node(ERRORS_CONTAINER_QNAME)
+            .node(ERRORS_CONTAINER_QNAME)
+            .build();
+
     static {
         XML_FACTORY = XMLOutputFactory.newFactory();
         XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
@@ -131,7 +142,7 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
                 SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) errorsSchemaNode);
 
         final List<DataSchemaNode> schemaList = ControllerContext.findInstanceDataChildrenByName(errorsSchemaNode,
-                Draft02.RestConfModule.ERROR_LIST_SCHEMA_NODE);
+                RestConfModule.ERROR_LIST_SCHEMA_NODE);
         final DataSchemaNode errListSchemaNode = Iterables.getFirst(schemaList, null);
         checkState(errListSchemaNode instanceof ListSchemaNode, "Found Error SchemaNode isn't ListSchemaNode");
         final CollectionNodeBuilder<MapEntryNode, SystemMapNode> listErorsBuilder = SchemaAwareBuilders
@@ -143,7 +154,7 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
         }
         errContBuild.withChild(listErorsBuilder.build());
 
-        final NormalizedNodeContext errContext =  new NormalizedNodeContext(new InstanceIdentifierContext<>(null,
+        final NormalizedNodeContext errContext =  new NormalizedNodeContext(new InstanceIdentifierContext<>(ERRORS,
                 (DataSchemaNode) errorsSchemaNode, null, controllerContext.getGlobalSchema()), errContBuild.build());
 
         Object responseBody;
@@ -197,7 +208,7 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
             // Oddly, error-info is defined as an empty container in the restconf yang. Apparently the
             // intention is for implementors to define their own data content so we'll just treat it as a leaf
             // with string data.
-            errNodeValues.withChild(ImmutableNodes.leafNode(Draft02.RestConfModule.ERROR_INFO_QNAME,
+            errNodeValues.withChild(ImmutableNodes.leafNode(RestConfModule.ERROR_INFO_QNAME,
                     error.getErrorInfo()));
         }
 
@@ -213,7 +224,6 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
         final InstanceIdentifierContext<?> context = errorsNode.getInstanceIdentifierContext();
         final DataSchemaNode schema = (DataSchemaNode) context.getSchemaNode();
 
-        SchemaPath path = context.getSchemaNode().getPath();
         final OutputStreamWriter outputWriter = new OutputStreamWriter(outStream, StandardCharsets.UTF_8);
         if (data == null) {
             throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
@@ -221,11 +231,17 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
 
         boolean isDataRoot = false;
         XMLNamespace initialNs = null;
-        if (SchemaPath.ROOT.equals(path)) {
+        SchemaPath path;
+        if (context.getSchemaNode() instanceof SchemaContext) {
             isDataRoot = true;
+            path = SchemaPath.ROOT;
         } else {
-            path = path.getParent();
-            // FIXME: Add proper handling of reading root.
+            final List<QName> qNames = context.getInstanceIdentifier().getPathArguments().stream()
+                    .filter(arg -> !(arg instanceof NodeIdentifierWithPredicates))
+                    .filter(arg -> !(arg instanceof AugmentationIdentifier))
+                    .map(PathArgument::getNodeType)
+                    .collect(Collectors.toList());
+            path = SchemaPath.of(Absolute.of(qNames)).getParent();
         }
         if (!schema.isAugmenting() && !(schema instanceof SchemaContext)) {
             initialNs = schema.getQName().getNamespace();
@@ -251,9 +267,9 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
 
             @Override
             public void startLeafNode(final NodeIdentifier name) throws IOException {
-                if (name.getNodeType().equals(Draft02.RestConfModule.ERROR_INFO_QNAME)) {
+                if (name.getNodeType().equals(RestConfModule.ERROR_INFO_QNAME)) {
                     inOurLeaf = true;
-                    jsonWriter.name(Draft02.RestConfModule.ERROR_INFO_QNAME.getLocalName());
+                    jsonWriter.name(RestConfModule.ERROR_INFO_QNAME.getLocalName());
                 } else {
                     super.startLeafNode(name);
                 }
@@ -317,13 +333,18 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
             throw new IllegalStateException(e);
         }
         NormalizedNode data = errorsNode.getData();
-        SchemaPath schemaPath = pathContext.getSchemaNode().getPath();
-
+        SchemaPath schemaPath;
         boolean isDataRoot = false;
-        if (SchemaPath.ROOT.equals(schemaPath)) {
+        if (pathContext.getSchemaNode() instanceof SchemaContext) {
             isDataRoot = true;
+            schemaPath = SchemaPath.ROOT;
         } else {
-            schemaPath = schemaPath.getParent();
+            final List<QName> qNames = pathContext.getInstanceIdentifier().getPathArguments().stream()
+                    .filter(arg -> !(arg instanceof NodeIdentifierWithPredicates))
+                    .filter(arg -> !(arg instanceof AugmentationIdentifier))
+                    .map(PathArgument::getNodeType)
+                    .collect(Collectors.toList());
+            schemaPath = SchemaPath.of(Absolute.of(qNames)).getParent();
         }
 
         final NormalizedNodeStreamWriter xmlStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
@@ -344,11 +365,11 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
 
             @Override
             public void startLeafNode(final NodeIdentifier name) throws IOException {
-                if (name.getNodeType().equals(Draft02.RestConfModule.ERROR_INFO_QNAME)) {
-                    String ns = Draft02.RestConfModule.ERROR_INFO_QNAME.getNamespace().toString();
+                if (name.getNodeType().equals(RestConfModule.ERROR_INFO_QNAME)) {
+                    String ns = RestConfModule.ERROR_INFO_QNAME.getNamespace().toString();
                     try {
                         xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX,
-                                Draft02.RestConfModule.ERROR_INFO_QNAME.getLocalName(), ns);
+                                RestConfModule.ERROR_INFO_QNAME.getLocalName(), ns);
                     } catch (XMLStreamException e) {
                         throw new IOException("Error writing error-info", e);
                     }