aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVidyashree Rama <vidyashree.rama@huawei.com>2018-08-17 12:21:05 +0530
committerVidyashree Rama <vidyashree.rama@huawei.com>2018-08-17 12:21:05 +0530
commit21190939f08b40c46f908fefabf8cc13e7365f2a (patch)
treed37d9bf2b2b575a8d4f9a6c08538103dd14b6860
parent436c3a034313ef7f27e6df32a33c667d7c89940b (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>
-rwxr-xr-xrestconf-client/provider/pom.xml6
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java133
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java11
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java11
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java84
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java297
-rw-r--r--restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java129
7 files changed, 645 insertions, 26 deletions
diff --git a/restconf-client/provider/pom.xml b/restconf-client/provider/pom.xml
index 5a74d8fc..46e00009 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 21f0b7c0..063c3d05 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 aa10e330..94892dca 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 9d1168b8..ba9da54c 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 05e1ac1e..405e2412 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 00000000..fb57d63b
--- /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 5cb8e4c9..0159683a 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;
}
}