diff options
author | Vidyashree Rama <vidyashree.rama@huawei.com> | 2018-08-17 12:21:05 +0530 |
---|---|---|
committer | Vidyashree Rama <vidyashree.rama@huawei.com> | 2018-08-17 12:21:05 +0530 |
commit | 21190939f08b40c46f908fefabf8cc13e7365f2a (patch) | |
tree | d37d9bf2b2b575a8d4f9a6c08538103dd14b6860 | |
parent | 436c3a034313ef7f27e6df32a33c667d7c89940b (diff) |
Implementation for properties node serializer
properties node serializer implementation
Issue-ID: CCSDK-378
Change-Id: I4eeecb45227e4152d9ff81551fd98efdd1371f84
Signed-off-by: Vidyashree Rama <vidyashree.rama@huawei.com>
7 files changed, 645 insertions, 26 deletions
diff --git a/restconf-client/provider/pom.xml b/restconf-client/provider/pom.xml index 5a74d8fc0..46e000094 100755 --- a/restconf-client/provider/pom.xml +++ b/restconf-client/provider/pom.xml @@ -70,5 +70,11 @@ <artifactId>properties-node-provider</artifactId> <version>0.3.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-data-impl</artifactId> + <version>2.0.3</version> + </dependency> + </dependencies> </project> diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java index 21f0b7c03..063c3d050 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java @@ -21,10 +21,22 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import java.util.HashMap; import java.util.Map; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getUri; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.isNamespaceAsParent; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE; +import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findCorrespondingAugment; + /** * Abstraction of an entity that represents an inner node to properties data * tree. @@ -62,8 +74,31 @@ public abstract class InnerNode<T extends NodeChild> extends PropertiesNode { public PropertiesNode addChild(String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + PropertiesNode node = ((PropertiesNode) children.get(name)); + if (node != null) { + return node; + } + + // get augment schema, if it is augmented node + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, name); + } + + // create node based on type + if (node == null) { + String uri = getUri(this, name, namespace); + node = createNode(name, namespace, uri, this, appInfo, type); + } + + // If namespace is not same as parent then it is augmented node + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override @@ -71,16 +106,65 @@ public abstract class InnerNode<T extends NodeChild> extends PropertiesNode { NodeType type, String value, Namespace valuens, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + LeafNode node = ((LeafNode) children.get(name)); + if (node != null) { + return node; + } + + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + } + + String uri = getUri(this, name, namespace); + node = new LeafNode(name, namespace, uri, this, + appInfo, type, value); + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override public PropertiesNode addChild(String index, String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localname = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localname)); + + if (node == null) { + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localname); + } + + if (node == null) { + String uri = getUri(this, name, namespace); + node = new ListHolderNode(localname, namespace, uri, + this, appInfo, MULTI_INSTANCE_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localname, ((T) node)); + } + + node = node.addChild(index, localname, namespace, type, appInfo); + } else if (node instanceof ListHolderNode) { + ListHolderChild child = ((ListHolderNode) node).child(index); + node = (child != null ? ((MultiInstanceNode) child) : + node.addChild(index, localname, namespace, type, appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } @Override @@ -88,7 +172,40 @@ public abstract class InnerNode<T extends NodeChild> extends PropertiesNode { Namespace namespace, NodeType type, String value, Namespace valueNs, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localName = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localName)); + + if (node == null) { + + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localName); + } + + if (node == null) { + String uri = getUri(this, name, namespace); + node = new LeafListHolderNode(localName, namespace, uri, this, + appInfo, MULTI_INSTANCE_LEAF_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localName, ((T) node)); + } + + node = node.addChild(index, localName, namespace, type, value, null, appInfo); + } else if (node instanceof LeafListHolderNode) { + LeafNode child = ((LeafNode) ((HolderNode) node).child(index)); + node = (child != null ? child : node.addChild(index, localName, + namespace, type, + value, null, + appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java index aa10e3307..94892dcac 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java @@ -75,7 +75,14 @@ public class LeafListHolderNode extends HolderNode<LeafListHolderChild> implemen Namespace namespace, NodeType type, String value, Namespace valueNs, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + LeafNode node = ((LeafNode) children().get(index)); + if (index == null) { + index = String.valueOf(children().size()); + } + String uri = this.uri() + "[" + index + "]"; + node = (node != null) ? node : new LeafNode(name, namespace, uri, + this, appInfo, type, value); + children().put(index, node); + return node; } } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java index 9d1168b8f..ba9da54cf 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java @@ -52,8 +52,15 @@ public class ListHolderNode extends HolderNode<ListHolderChild> implements DataN public PropertiesNode addChild(String index, String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + MultiInstanceNode node = ((MultiInstanceNode) children().get(index)); + if (index == null) { + index = String.valueOf(children().size()); + } + String uri = this.uri() + "[" + index + "]"; + node = (node != null) ? node : new MultiInstanceNode(name, namespace, uri, + this, appInfo, type); + children().put(index, node); + return node; } @Override diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java index 05e1ac1e6..405e24127 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java @@ -20,13 +20,25 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.slf4j.Logger; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import java.util.Map; -import static org.slf4j.LoggerFactory.getLogger; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getChildSchemaNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getIndex; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getListName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNamespace; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNodeType; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE; /** * Representation of mdsal based properties node serializer implementation. @@ -35,7 +47,6 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche private SchemaNode curSchema; private PropertiesNode node; - private static final Logger LOG = getLogger(MdsalPropertiesNodeSerializer.class); /** * Creates the properties node serializer. @@ -44,13 +55,33 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche * @param schemaCtx schema context * @param uri URL of the request */ - public MdsalPropertiesNodeSerializer(SchemaNode schemaNode, SchemaContext schemaCtx, String uri) { + public MdsalPropertiesNodeSerializer(SchemaNode schemaNode, + SchemaContext schemaCtx, String uri) { super(schemaNode, schemaCtx, uri); } @Override - public PropertiesNode encode(Map<String, String> paramMap) { - return null; + public PropertiesNode encode(Map<String, String> paramMap) throws SvcLogicException { + curSchema = schemaNode(); + String nodeInUri[] = uri().split("\\/"); + String lastNodeName = nodeInUri[nodeInUri.length - 1]; + String rootUri = uri().replaceAll("\\/", "\\."); + node = createRootNode(lastNodeName, rootUri); + + for (Map.Entry<String, String> entry : paramMap.entrySet()) { + String[] names = entry.getKey().split("\\."); + for (int i = 0; i < names.length; i++) { + if (i < nodeInUri.length) { + if (!(nodeInUri[i].equals(names[i]))) { + break; + } + } else { + createPropertyNode(i, names.length, names[i], + entry.getValue()); + } + } + } + return node; } @Override @@ -58,4 +89,45 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche return null; } + private RootNode createRootNode(String lastNodeName, String rootUri) { + Module m = SchemaContextUtil.findParentModule(schemaCtx(), curSchema); + Namespace ns = new Namespace(m.getName(), m.getNamespace(), + getRevision(m.getRevision())); + return new RootNode(lastNodeName, ns, schemaNode(), rootUri); + } + + private void createPropertyNode(int index, int length, String name, + String value) throws SvcLogicException { + String localName = resolveName(name); + Namespace ns = getNamespace(getListName(name), schemaCtx(), node); + SchemaNode schema = getChildSchemaNode(curSchema, localName, ns); + if (schema == null) { + return; + } + + switch (getNodeType(index, length, name)) { + case SINGLE_INSTANCE_NODE: + node = node.addChild(localName, ns, + SINGLE_INSTANCE_NODE, schema); + curSchema = schema; + break; + case MULTI_INSTANCE_NODE: + node = node.addChild(getIndex(name), localName, ns, + MULTI_INSTANCE_NODE, schema); + curSchema = schema; + break; + case SINGLE_INSTANCE_LEAF_NODE: + node = node.addChild(localName, ns, SINGLE_INSTANCE_LEAF_NODE, + value, null, schema); + node = node.endNode(); + curSchema = ((SchemaNode) node.appInfo()); + break; + case MULTI_INSTANCE_LEAF_NODE: + node = node.addChild(getIndex(name), localName, ns, + MULTI_INSTANCE_LEAF_NODE, value, null, schema); + node = node.endNode(); + curSchema = ((SchemaNode) node.appInfo()); + break; + } + } } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java new file mode 100644 index 000000000..fb57d63bd --- /dev/null +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java @@ -0,0 +1,297 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - CCSDK + * ================================================================================ + * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils; +import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; + +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; +import java.util.Optional; + +/** + * Represents utilities for properties node tree. + */ +public final class MdsalPropertiesNodeUtils { + + private MdsalPropertiesNodeUtils() { + } + + /** + * Returns the index from multi instance property name. + * + * @param name name of the property + * @return index from multi instance property name + */ + public static String getIndex(String name) { + return name.substring(name.indexOf("[") + 1, + name.indexOf("]")); + } + + /** + * Returns the multi instance property name. + * + * @param name name of the property + * @return the multi instance property name + */ + public static String getListName(String name) { + String[] s = name.split("\\["); + return s[0]; + } + + /** + * Returns true if property is multi instance. + * + * @param name name of the property + * @return true if property is multi instance + */ + public static boolean isListEntry(String name) { + String s[] = name.split("\\["); + return s.length > 1; + } + + /** + * Returns name of the property after pruning namespace and + * index if the property is multi instance. + * + * @param name name of the property + * @return name of the property + */ + public static String resolveName(String name) { + String localName = getListName(name); + final int lastIndexOfColon = localName.lastIndexOf(":"); + if (lastIndexOfColon != -1) { + localName = localName.substring(lastIndexOfColon + 1); + } + return localName; + } + + /** + * Adds current node to parent's augmentation map. + * + * @param augSchema augment schema + * @param parent parent property node + * @param curNode current property node + */ + public static void addToAugmentations(AugmentationSchemaNode augSchema, + PropertiesNode parent, + PropertiesNode curNode) { + Collection<PropertiesNode> childsFromAugmentation = parent + .augmentations().get(augSchema); + if (!childsFromAugmentation.isEmpty()) { + for (PropertiesNode pNode : childsFromAugmentation) { + if (pNode.name().equals(curNode.name())) { + return; + } + } + } + parent.augmentations().put(augSchema, curNode); + } + + + /** + * Returns augmented properties node if it is already + * added in properties tree. + * + * @param augSchema augmented schema node + * @param parent parent properties node + * @param name name of the properties + * @return augmented properties node if it is already added + */ + public static PropertiesNode getAugmentationNode( + AugmentationSchemaNode augSchema, + PropertiesNode parent, String name) { + if (augSchema != null) { + Collection<PropertiesNode> childsFromAugmentation = parent + .augmentations().get(augSchema); + if (!childsFromAugmentation.isEmpty()) { + for (PropertiesNode pNode : childsFromAugmentation) { + if (pNode.name().equals(name)) { + return pNode; + } + } + } + } + return null; + } + + /** + * Creates uri with specified name and namespace. + * + * @param parent parent properties node + * @param name name of the node + * @param ns namespace of the node + * @return uri with specified name and namespace + */ + public static String getUri(PropertiesNode parent, String name, + Namespace ns) { + String uri = name; + if (!(parent.namespace().moduleNs().equals(ns.moduleNs()))) { + uri = ns.moduleName() + ":" + name; + } + return parent.uri() + "." + uri; + } + + /** + * Creates new properties with specified parameters. + * + * @param name name of the properties node + * @param namespace namespace of the properties node + * @param uri uri of the properties node + * @param parent parent node + * @param appInfo application info + * @param type node type + * @return new properties node + */ + public static PropertiesNode createNode(String name, Namespace namespace, + String uri, PropertiesNode parent, + Object appInfo, NodeType type) { + switch (type) { + case SINGLE_INSTANCE_NODE: + return new SingleInstanceNode(name, namespace, uri, parent, appInfo, type); + case MULTI_INSTANCE_HOLDER_NODE: + return new ListHolderNode(name, namespace, uri, parent, appInfo, type); + case MULTI_INSTANCE_LEAF_HOLDER_NODE: + return new LeafListHolderNode(name, namespace, uri, parent, appInfo, type); + default: + throw new RuntimeException("Invalid node type"); + } + } + + /** + * Returns true if namespace is same as parent's namespace. + * + * @param parent parent property node + * @param curNode current property node + * @return true if namespace is same as parent namespace + */ + public static boolean isNamespaceAsParent(PropertiesNode parent, + PropertiesNode curNode) { + return parent.namespace().moduleNs().equals(curNode.namespace().moduleNs()); + } + + /** + * Returns namespace. + * + * @param childName name of the property + * @param ctx schema context + * @param parent parent property node + * @return namespace + */ + public static Namespace getNamespace(String childName, + SchemaContext ctx, + PropertiesNode parent) { + int lastIndexOfColon = childName.lastIndexOf(":"); + if (lastIndexOfColon != -1) { + String moduleName = childName.substring(0, lastIndexOfColon); + Iterator<Module> it = ctx.findModules(moduleName).iterator(); + if (!it.hasNext()) { + // module is not present in context + return null; + } + Module m = it.next(); + return new Namespace(moduleName, m.getQNameModule().getNamespace(), + getRevision(m.getRevision())); + } + Namespace parentNs = parent.namespace(); + return new Namespace(parentNs.moduleName(), parentNs.moduleNs(), + parentNs.revision()); + } + + /** + * Returns child schema node. + * + * @param curSchema current schema node + * @param name name of the property + * @param namespace namespace of the property + * @return child schema node + */ + public static SchemaNode getChildSchemaNode(SchemaNode curSchema, + String name, + Namespace namespace) { + if (namespace == null) { + return null; + } + + QName qname = QName.create(namespace.moduleNs(), + Revision.of(namespace.revision()), name); + + // YANG RPC will not be instance of DataSchemaNode + if (curSchema instanceof DataSchemaNode) { + Deque<DataSchemaNode> schemaNodeDeque = ParserStreamUtils. + findSchemaNodeByNameAndNamespace(((DataSchemaNode) + curSchema), name, namespace.moduleNs()); + if (schemaNodeDeque.isEmpty()) { + // could not find schema node + return null; + } + + DataSchemaNode schemaNode = schemaNodeDeque.pop(); + if (schemaNodeDeque.isEmpty()){ + // Simple node + return schemaNode; + } + + // node is child of Choice/case + return SchemaUtils.findSchemaForChild(((ChoiceSchemaNode) schemaNode), + qname); + } else { + return SchemaUtils.findDataChildSchemaByQName(curSchema, qname); + } + } + + /** + * Returns the property node type. + * + * @param index current index + * @param length length of the properties + * @param name name of the property + * @return the property node type + */ + public static NodeType getNodeType(int index, int length, String name) { + if (index == length-1) { + return (isListEntry(name) ? NodeType.MULTI_INSTANCE_LEAF_NODE : + NodeType.SINGLE_INSTANCE_LEAF_NODE); + } else { + return (isListEntry(name) ? NodeType.MULTI_INSTANCE_NODE : + NodeType.SINGLE_INSTANCE_NODE); + } + } + + /** + * Returns revision in string. + * + * @param r YANG revision + * @return revision in string + */ + public static String getRevision(Optional<Revision> r) { + return (r.isPresent()) ? r.get().toString() : null; + } +} diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java index 5cb8e4c97..0159683ac 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java @@ -21,10 +21,22 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import java.util.HashMap; import java.util.Map; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getUri; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.isNamespaceAsParent; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE; +import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findCorrespondingAugment; + /** * Abstraction of node representing properties data tree. */ @@ -59,8 +71,32 @@ public class RootNode<T extends NodeChild> extends PropertiesNode { public PropertiesNode addChild(String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + PropertiesNode node = ((PropertiesNode) children.get(name)); + if (node != null) { + return node; + } + + // get augment schema, if it is augmented node + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, name); + } + + // create node based on type, this api will be invoked only for these three types + if (node == null) { + String uri = getUri(this, name, namespace); + node = createNode(name, namespace, uri, this, appInfo, type); + } + + // If namespace is not same as parent then it is augmented node + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override @@ -68,16 +104,63 @@ public class RootNode<T extends NodeChild> extends PropertiesNode { NodeType type, String value, Namespace valuens, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + LeafNode node = ((LeafNode) children.get(name)); + if (node != null) { + return node; + } + + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + } + + String uri = getUri(this, name, namespace); + node = new LeafNode(name, namespace, uri, this, + appInfo, type, value); + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override public PropertiesNode addChild(String index, String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localname = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localname)); + if (node == null) { + String uri = getUri(this, name, namespace); + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localname); + } + + if (node == null) { + node = new ListHolderNode(localname, namespace, uri, + this, appInfo, MULTI_INSTANCE_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localname, ((T) node)); + } + node = node.addChild(index, localname, namespace, type, appInfo); + } else if (node instanceof ListHolderNode) { + ListHolderChild child = ((ListHolderNode) node).child(index); + node = (child != null ? ((MultiInstanceNode) child) : + node.addChild(index, localname, namespace, type, appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } @Override @@ -85,7 +168,37 @@ public class RootNode<T extends NodeChild> extends PropertiesNode { Namespace namespace, NodeType type, String value, Namespace valueNs, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localName = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localName)); + if (node == null) { + String uri = getUri(this, name, namespace); + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localName); + } + + if (node == null) { + node = new LeafListHolderNode(localName, namespace, uri, this, + appInfo, MULTI_INSTANCE_LEAF_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localName, ((T) node)); + } + node = node.addChild(index, localName, namespace, type, value, null, appInfo); + } else if (node instanceof LeafListHolderNode) { + LeafNode child = ((LeafNode) ((HolderNode) node).child(index)); + node = (child != null ? child : node.addChild(index, localName, + namespace, type, + value, null, + appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } } |