X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-service%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fcps%2Fspi%2Fmodel%2FDataNodeBuilder.java;h=9859acdf0efd237cc7f26ec5f5627ef814494593;hb=e2d88379376923fbdddc78b59f74d75fd8040ec6;hp=cd6a3a2201b4224e3587aeea8d74a011285efcaa;hpb=a54fd8a169e8e6ef74bdc06be78bbcd70d5f97b4;p=cps.git diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java index cd6a3a220..9859acdf0 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java +++ b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java @@ -1,6 +1,9 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2021 Pantheon.tech + * Modifications Copyright (C) 2022-2024 Nordix Foundation. + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,15 +24,21 @@ package org.onap.cps.spi.model; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import java.io.Serializable; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Optional; 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.common.Ordering; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +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.DataContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; @@ -40,24 +49,40 @@ import org.opendaylight.yangtools.yang.data.api.schema.ValueNode; @Slf4j public class DataNodeBuilder { - private NormalizedNode normalizedNodeTree; + private ContainerNode containerNode; private String xpath; + private String moduleNamePrefix; + private String parentNodeXpath = ""; + private Map leaves = Collections.emptyMap(); private Collection childDataNodes = Collections.emptySet(); + private String dataspaceName; + private String anchorName; - - /** To use {@link NormalizedNode} for creating {@link DataNode}. + /** + * To use parent node xpath for creating {@link DataNode}. * - * @param normalizedNodeTree used for creating the Data Node + * @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 Collection} of Normalized Nodes for creating {@link DataNode}. * + * @param containerNode used for creating the Data Node * @return this {@link DataNodeBuilder} object */ - public DataNodeBuilder withNormalizedNodeTree(final NormalizedNode normalizedNodeTree) { - this.normalizedNodeTree = normalizedNodeTree; + public DataNodeBuilder withContainerNode(final ContainerNode containerNode) { + this.containerNode = containerNode; return this; } /** * To use xpath for creating {@link DataNode}. + * * @param xpath for the data node * @return DataNodeBuilder */ @@ -66,8 +91,53 @@ public class DataNodeBuilder { return this; } + /** + * To use dataspace name for creating {@link DataNode}. + * + * @param dataspaceName dataspace name for the data node + * @return DataNodeBuilder + */ + public DataNodeBuilder withDataspace(final String dataspaceName) { + this.dataspaceName = dataspaceName; + return this; + } + + /** + * To use anchor name for creating {@link DataNode}. + * + * @param anchorName anchor name for the data node + * @return DataNodeBuilder + */ + public DataNodeBuilder withAnchor(final String anchorName) { + this.anchorName = anchorName; + return this; + } + + /** + * To use module name for prefix for creating {@link DataNode}. + * + * @param moduleNamePrefix module name as prefix + * @return DataNodeBuilder + */ + public DataNodeBuilder withModuleNamePrefix(final String moduleNamePrefix) { + this.moduleNamePrefix = moduleNamePrefix; + return this; + } + + /** + * To use attributes for creating {@link DataNode}. + * + * @param leaves for the data node + * @return DataNodeBuilder + */ + public DataNodeBuilder withLeaves(final Map leaves) { + this.leaves = leaves; + return this; + } + /** * To specify child nodes needs to be used while creating {@link DataNode}. + * * @param childDataNodes to be added to the dataNode * @return DataNodeBuilder */ @@ -84,86 +154,117 @@ public class DataNodeBuilder { * @return {@link DataNode} */ public DataNode build() { - if (normalizedNodeTree != null) { - return buildFromNormalizedNodeTree(); - } else { - return buildFromAttributes(); + if (containerNode != null) { + return buildFromContainerNode(); + } + return buildFromAttributes(); + } + + /** + * To build a {@link Collection} of {@link DataNode} objects. + * + * @return {@link DataNode} {@link Collection} + */ + public Collection buildCollection() { + if (containerNode != null) { + return buildCollectionFromContainerNode(); } + return Collections.emptySet(); } private DataNode buildFromAttributes() { - final DataNode dataNode = new DataNode(); + final var dataNode = new DataNode(); dataNode.setXpath(xpath); + dataNode.setModuleNamePrefix(moduleNamePrefix); + dataNode.setLeaves(leaves); dataNode.setChildDataNodes(childDataNodes); + dataNode.setDataspace(dataspaceName); + dataNode.setAnchorName(anchorName); return dataNode; } - private DataNode buildFromNormalizedNodeTree() { - xpath = YangUtils.buildXpath(normalizedNodeTree.getIdentifier()); - final DataNode dataNode = new DataNodeBuilder().withXpath(xpath).build(); - addDataNodeFromNormalizedNode(dataNode, normalizedNodeTree); - return dataNode; + private DataNode buildFromContainerNode() { + final Collection dataNodeCollection = buildCollectionFromContainerNode(); + if (dataNodeCollection.isEmpty()) { + throw new DataValidationException("Unsupported Normalized Node", "No valid node found"); + } + return dataNodeCollection.iterator().next(); + } + + private Collection buildCollectionFromContainerNode() { + final var parentDataNode = new DataNodeBuilder().withXpath(parentNodeXpath).build(); + if (containerNode.body() != null) { + for (final NormalizedNode normalizedNode: containerNode.body()) { + addDataNodeFromNormalizedNode(parentDataNode, normalizedNode); + } + } + return parentDataNode.getChildDataNodes(); } - private void addDataNodeFromNormalizedNode(final DataNode currentDataNode, + private static void addDataNodeFromNormalizedNode(final DataNode currentDataNode, final NormalizedNode normalizedNode) { - if (normalizedNode instanceof DataContainerNode) { + + if (normalizedNode instanceof ChoiceNode) { + addChoiceNode(currentDataNode, (ChoiceNode) normalizedNode); + } else if (normalizedNode instanceof DataContainerNode) { addYangContainer(currentDataNode, (DataContainerNode) normalizedNode); } else if (normalizedNode instanceof MapNode) { addDataNodeForEachListElement(currentDataNode, (MapNode) normalizedNode); } else if (normalizedNode instanceof ValueNode) { - final ValueNode valuesNode = (ValueNode) normalizedNode; - addYangLeaf(currentDataNode, valuesNode.getNodeType().getLocalName(), valuesNode.getValue()); + final ValueNode valuesNode = (ValueNode) normalizedNode; + addYangLeaf(currentDataNode, valuesNode.getIdentifier().getNodeType().getLocalName(), + (Serializable) valuesNode.body()); } else if (normalizedNode instanceof LeafSetNode) { - addYangLeafList(currentDataNode, (LeafSetNode) normalizedNode); + addYangLeafList(currentDataNode, (LeafSetNode) normalizedNode); } else { - log.warn("Cannot normalize {}", normalizedNode.getClass()); + log.warn("Unsupported NormalizedNode type detected: {}", normalizedNode.getClass()); } } - private void addYangContainer(final DataNode currentDataNode, final DataContainerNode dataContainerNode) { - final Collection normalizedChildNodes = dataContainerNode.getValue(); + private static void addYangContainer(final DataNode currentDataNode, final DataContainerNode dataContainerNode) { + final DataNode dataContainerDataNode = + (dataContainerNode.getIdentifier() instanceof YangInstanceIdentifier.AugmentationIdentifier) + ? currentDataNode + : createAndAddChildDataNode(currentDataNode, YangUtils.buildXpath(dataContainerNode.getIdentifier())); + final Collection normalizedChildNodes = dataContainerNode.body(); for (final NormalizedNode normalizedNode : normalizedChildNodes) { - addDataNodeFromNormalizedNode(currentDataNode, normalizedNode); + addDataNodeFromNormalizedNode(dataContainerDataNode, normalizedNode); } } - private void addYangLeaf(final DataNode currentDataNode, final String leafName, final Object leafValue) { - final Map leaves = new ImmutableMap.Builder() + private static void addYangLeaf(final DataNode currentDataNode, final String leafName, + final Serializable leafValue) { + final Map leaves = new ImmutableMap.Builder() .putAll(currentDataNode.getLeaves()) .put(leafName, leafValue) .build(); currentDataNode.setLeaves(leaves); } - private void addYangLeafList(final DataNode currentDataNode, final LeafSetNode leafSetNode) { - final ImmutableSet.Builder builder = new ImmutableSet.Builder(); - final String leafListName = leafSetNode.getNodeType().getLocalName(); - final Optional> optionalLeafListNames = currentDataNode.getOptionalLeafListNames(); - if (optionalLeafListNames.isPresent()) { - builder.addAll(optionalLeafListNames.get()); - } - builder.add(leafListName); - final ImmutableSet leafListNames = builder.build(); - currentDataNode.setOptionalLeafListNames(Optional.of(leafListNames)); - final List leafListValues = new LinkedList(); - for (final NormalizedNode normalizedNode : (Collection) leafSetNode.getValue()) { - leafListValues.add(((ValueNode) normalizedNode).getValue()); + private static void addYangLeafList(final DataNode currentDataNode, final LeafSetNode leafSetNode) { + final String leafListName = leafSetNode.getIdentifier().getNodeType().getLocalName(); + List leafListValues = ((Collection) leafSetNode.body()) + .stream() + .map(NormalizedNode::body) + .collect(Collectors.toList()); + if (leafSetNode.ordering() == Ordering.SYSTEM) { + leafListValues.sort(null); } - addYangLeaf(currentDataNode, leafListName, leafListValues); + leafListValues = Collections.unmodifiableList(leafListValues); + addYangLeaf(currentDataNode, leafListName, (Serializable) leafListValues); } - private void addDataNodeForEachListElement(final DataNode currentDataNode, final MapNode mapNode) { - final Collection mapEntryNodes = mapNode.getValue(); + private static void addDataNodeForEachListElement(final DataNode currentDataNode, final MapNode mapNode) { + final Collection mapEntryNodes = mapNode.body(); for (final MapEntryNode mapEntryNode : mapEntryNodes) { - final String xpathChild = YangUtils.buildXpath(mapEntryNode.getIdentifier()); - final DataNode childDataNode = createAndAddChildDataNode(currentDataNode, xpathChild); - addDataNodeFromNormalizedNode(childDataNode, mapEntryNode); + addDataNodeFromNormalizedNode(currentDataNode, mapEntryNode); } } - private DataNode createAndAddChildDataNode(final DataNode parentDataNode, final String childXpath) { - final DataNode newChildDataNode = new DataNodeBuilder().withXpath(xpath + childXpath) + private static DataNode createAndAddChildDataNode(final DataNode parentDataNode, final String childXpath) { + + final var newChildDataNode = new DataNodeBuilder() + .withXpath(parentDataNode.getXpath() + childXpath) .build(); final Set allChildDataNodes = new ImmutableSet.Builder() .addAll(parentDataNode.getChildDataNodes()) @@ -173,4 +274,12 @@ public class DataNodeBuilder { return newChildDataNode; } + private static void addChoiceNode(final DataNode currentDataNode, final ChoiceNode choiceNode) { + + final Collection normalizedChildNodes = choiceNode.body(); + for (final NormalizedNode normalizedNode : normalizedChildNodes) { + addDataNodeFromNormalizedNode(currentDataNode, normalizedNode); + } + } + }