Updating exception and explanation for update node leaves
[cps.git] / cps-service / src / main / java / org / onap / cps / spi / model / DataNodeBuilder.java
index d187f62..4a9957d 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2021 Bell Canada. All rights reserved.
+ *  Modifications Copyright (C) 2021 Pantheon.tech
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -28,7 +29,9 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.spi.exceptions.DataValidationException;
 import org.onap.cps.utils.YangUtils;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
@@ -42,8 +45,21 @@ public class DataNodeBuilder {
 
     private NormalizedNode<?, ?> normalizedNodeTree;
     private String xpath;
+    private String parentNodeXpath = "";
+    private Map<String, Object> leaves = Collections.emptyMap();
     private Collection<DataNode> childDataNodes = Collections.emptySet();
 
+    /**
+     * To use parent node xpath for creating {@link DataNode}.
+     *
+     * @param parentNodeXpath xpath of a parent node
+     * @return this {@link DataNodeBuilder} object
+     */
+    public DataNodeBuilder withParentNodeXpath(final String parentNodeXpath) {
+        this.parentNodeXpath = parentNodeXpath;
+        return this;
+    }
+
 
     /**
      * To use {@link NormalizedNode} for creating {@link DataNode}.
@@ -67,6 +83,17 @@ public class DataNodeBuilder {
         return this;
     }
 
+    /**
+     * To use attributes for creating {@link DataNode}.
+     *
+     * @param leaves for the data node
+     * @return DataNodeBuilder
+     */
+    public DataNodeBuilder withLeaves(final Map<String, Object> leaves) {
+        this.leaves = leaves;
+        return this;
+    }
+
     /**
      * To specify child nodes needs to be used while creating {@link DataNode}.
      *
@@ -93,17 +120,40 @@ public class DataNodeBuilder {
         }
     }
 
+    /**
+     * To build a {@link Collection} of {@link DataNode} objects.
+     *
+     * @return {@link DataNode} {@link Collection}
+     */
+    public Collection<DataNode> buildCollection() {
+        if (normalizedNodeTree != null) {
+            return buildCollectionFromNormalizedNodeTree();
+        } else {
+            return Set.of(buildFromAttributes());
+        }
+    }
+
     private DataNode buildFromAttributes() {
-        final DataNode dataNode = new DataNode();
+        final var dataNode = new DataNode();
         dataNode.setXpath(xpath);
+        dataNode.setLeaves(leaves);
         dataNode.setChildDataNodes(childDataNodes);
         return dataNode;
     }
 
     private DataNode buildFromNormalizedNodeTree() {
-        final DataNode formalRootDataNode = new DataNodeBuilder().withXpath("").build();
-        addDataNodeFromNormalizedNode(formalRootDataNode, normalizedNodeTree);
-        return formalRootDataNode.getChildDataNodes().iterator().next();
+        final Collection<DataNode> dataNodeCollection = buildCollectionFromNormalizedNodeTree();
+        if (!dataNodeCollection.iterator().hasNext()) {
+            throw new DataValidationException(
+                "Unsupported xpath: ", "Unsupported xpath as it is referring to one element");
+        }
+        return dataNodeCollection.iterator().next();
+    }
+
+    private Collection<DataNode> buildCollectionFromNormalizedNodeTree() {
+        final var parentDataNode = new DataNodeBuilder().withXpath(parentNodeXpath).build();
+        addDataNodeFromNormalizedNode(parentDataNode, normalizedNodeTree);
+        return parentDataNode.getChildDataNodes();
     }
 
     private static void addDataNodeFromNormalizedNode(final DataNode currentDataNode,
@@ -124,8 +174,10 @@ public class DataNodeBuilder {
     }
 
     private static void addYangContainer(final DataNode currentDataNode, final DataContainerNode<?> dataContainerNode) {
-        final DataNode dataContainerDataNode = createAndAddChildDataNode(currentDataNode,
-            YangUtils.buildXpath(dataContainerNode.getIdentifier()));
+        final DataNode dataContainerDataNode =
+            (dataContainerNode.getIdentifier() instanceof YangInstanceIdentifier.AugmentationIdentifier)
+                ? currentDataNode
+                : createAndAddChildDataNode(currentDataNode, YangUtils.buildXpath(dataContainerNode.getIdentifier()));
         final Collection<DataContainerChild<?, ?>> normalizedChildNodes = dataContainerNode.getValue();
         for (final NormalizedNode<?, ?> normalizedNode : normalizedChildNodes) {
             addDataNodeFromNormalizedNode(dataContainerDataNode, normalizedNode);
@@ -158,7 +210,7 @@ public class DataNodeBuilder {
 
     private static DataNode createAndAddChildDataNode(final DataNode parentDataNode, final String childXpath) {
 
-        final DataNode newChildDataNode = new DataNodeBuilder()
+        final var newChildDataNode = new DataNodeBuilder()
             .withXpath(parentDataNode.getXpath() + childXpath)
             .build();
         final Set<DataNode> allChildDataNodes = new ImmutableSet.Builder<DataNode>()