Merge "Docker image building and docker-compose for cps-nf-proxy"
[cps.git] / cps-service / src / main / java / org / onap / cps / spi / model / DataNodeBuilder.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Bell Canada. All rights reserved.
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.cps.spi.model;
21
22 import com.google.common.collect.ImmutableMap;
23 import com.google.common.collect.ImmutableSet;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Optional;
30 import java.util.Set;
31 import lombok.extern.slf4j.Slf4j;
32 import org.onap.cps.utils.YangUtils;
33 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.ValueNode;
39
40 @Slf4j
41 public class DataNodeBuilder {
42
43     private NormalizedNode normalizedNodeTree;
44     private String xpath;
45     private Collection<DataNode> childDataNodes = Collections.emptySet();
46
47
48     /** To use {@link NormalizedNode} for creating {@link DataNode}.
49      *
50      * @param normalizedNodeTree used for creating the Data Node
51      *
52      * @return this {@link DataNodeBuilder} object
53      */
54     public DataNodeBuilder withNormalizedNodeTree(final NormalizedNode normalizedNodeTree) {
55         this.normalizedNodeTree = normalizedNodeTree;
56         return this;
57     }
58
59     /**
60      * To use xpath for creating {@link DataNode}.
61      * @param xpath for the data node
62      * @return DataNodeBuilder
63      */
64     public DataNodeBuilder withXpath(final String xpath) {
65         this.xpath = xpath;
66         return this;
67     }
68
69     /**
70      * To specify child nodes needs to be used while creating {@link DataNode}.
71      * @param childDataNodes to be added to the dataNode
72      * @return DataNodeBuilder
73      */
74     public DataNodeBuilder withChildDataNodes(final Collection<DataNode> childDataNodes) {
75         // Added as this is being set from test cases .
76         // Open for suggestions
77         this.childDataNodes = childDataNodes;
78         return this;
79     }
80
81     /**
82      * To create the {@link DataNode}.
83      *
84      * @return {@link DataNode}
85      */
86     public DataNode build() {
87         if (normalizedNodeTree != null) {
88             return buildFromNormalizedNodeTree();
89         } else {
90             return buildFromAttributes();
91         }
92     }
93
94     private DataNode buildFromAttributes() {
95         final DataNode dataNode = new DataNode();
96         dataNode.setXpath(xpath);
97         dataNode.setChildDataNodes(childDataNodes);
98         return dataNode;
99     }
100
101     private DataNode buildFromNormalizedNodeTree() {
102         xpath = YangUtils.buildXpath(normalizedNodeTree.getIdentifier());
103         final DataNode dataNode = new DataNodeBuilder().withXpath(xpath).build();
104         addDataNodeFromNormalizedNode(dataNode, normalizedNodeTree);
105         return dataNode;
106     }
107
108     private void addDataNodeFromNormalizedNode(final DataNode currentDataNode,
109         final NormalizedNode normalizedNode) {
110         if (normalizedNode instanceof DataContainerNode) {
111             addYangContainer(currentDataNode, (DataContainerNode) normalizedNode);
112         } else if (normalizedNode instanceof MapNode) {
113             addDataNodeForEachListElement(currentDataNode, (MapNode) normalizedNode);
114         } else if (normalizedNode instanceof ValueNode) {
115             final ValueNode valuesNode = (ValueNode) normalizedNode;
116             addYangLeaf(currentDataNode, valuesNode.getNodeType().getLocalName(), valuesNode.getValue());
117         } else if (normalizedNode instanceof LeafSetNode) {
118             addYangLeafList(currentDataNode, (LeafSetNode) normalizedNode);
119         } else {
120             log.warn("Cannot normalize {}", normalizedNode.getClass());
121         }
122     }
123
124     private void addYangContainer(final DataNode currentDataNode, final DataContainerNode dataContainerNode) {
125         final Collection<NormalizedNode> normalizedChildNodes = dataContainerNode.getValue();
126         for (final NormalizedNode normalizedNode : normalizedChildNodes) {
127             addDataNodeFromNormalizedNode(currentDataNode, normalizedNode);
128         }
129     }
130
131     private void addYangLeaf(final DataNode currentDataNode, final String leafName, final Object leafValue) {
132         final Map leaves = new ImmutableMap.Builder<String, Object>()
133             .putAll(currentDataNode.getLeaves())
134             .put(leafName, leafValue)
135             .build();
136         currentDataNode.setLeaves(leaves);
137     }
138
139     private void addYangLeafList(final DataNode currentDataNode, final LeafSetNode leafSetNode) {
140         final ImmutableSet.Builder builder = new ImmutableSet.Builder<String>();
141         final String leafListName = leafSetNode.getNodeType().getLocalName();
142         final Optional<Set<String>> optionalLeafListNames = currentDataNode.getOptionalLeafListNames();
143         if (optionalLeafListNames.isPresent()) {
144             builder.addAll(optionalLeafListNames.get());
145         }
146         builder.add(leafListName);
147         final ImmutableSet leafListNames = builder.build();
148         currentDataNode.setOptionalLeafListNames(Optional.of(leafListNames));
149         final List leafListValues = new LinkedList();
150         for (final NormalizedNode normalizedNode : (Collection<NormalizedNode>) leafSetNode.getValue()) {
151             leafListValues.add(((ValueNode) normalizedNode).getValue());
152         }
153         addYangLeaf(currentDataNode, leafListName, leafListValues);
154     }
155
156     private void addDataNodeForEachListElement(final DataNode currentDataNode, final MapNode mapNode) {
157         final Collection<MapEntryNode> mapEntryNodes = mapNode.getValue();
158         for (final MapEntryNode mapEntryNode : mapEntryNodes) {
159             final String xpathChild = YangUtils.buildXpath(mapEntryNode.getIdentifier());
160             final DataNode childDataNode = createAndAddChildDataNode(currentDataNode, xpathChild);
161             addDataNodeFromNormalizedNode(childDataNode, mapEntryNode);
162         }
163     }
164
165     private DataNode createAndAddChildDataNode(final DataNode parentDataNode, final String childXpath) {
166         final DataNode newChildDataNode = new DataNodeBuilder().withXpath(xpath + childXpath)
167             .build();
168         final Set<DataNode> allChildDataNodes = new ImmutableSet.Builder<DataNode>()
169             .addAll(parentDataNode.getChildDataNodes())
170             .add(newChildDataNode)
171             .build();
172         parentDataNode.setChildDataNodes(allChildDataNodes);
173         return newChildDataNode;
174     }
175
176 }