[ONOS-5500] Properly encode namespaces in URI path segments
Change-Id: I166cbfb8e379a2029f0dab72be117a3afe74973e
diff --git a/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/ParserUtils.java b/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/ParserUtils.java
index bc959f0..5ede187 100755
--- a/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/ParserUtils.java
+++ b/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/ParserUtils.java
@@ -70,7 +70,7 @@
checkNotNull(id, "uri identifier should not be null");
List<String> paths = urlPathArgsDecode(SLASH_SPLITTER.split(id));
if (!paths.isEmpty()) {
- processPathSegments(paths, builder, opType);
+ processPathSegments(paths, builder, opType, true);
}
}
@@ -110,40 +110,102 @@
/**
* Converts a list of path segments to a YDT builder tree.
*
- * @param paths the list of path segments split from URI
- * @param builder the base YDT builder
- * @param opType the YDT operation type for the Path segment
+ * @param paths the list of path segments split from URI
+ * @param builder the base YDT builder
+ * @param opType the YDT operation type for the Path segment
+ * @param isFirstIteration true if paths contains all the URI segments
* @return the YDT builder with the tree info of paths
*/
private static YdtBuilder processPathSegments(List<String> paths,
YdtBuilder builder,
- YdtContextOperationType opType) {
+ YdtContextOperationType opType,
+ boolean isFirstIteration) {
if (paths.isEmpty()) {
return builder;
}
- boolean isLastNode = paths.size() == 1;
- YdtContextOperationType opTypeForThisNode = isLastNode ? opType : NONE;
- String path = paths.iterator().next();
- if (path.contains(COLON)) {
- addModule(builder, path);
- addNode(path, builder, opTypeForThisNode);
- } else if (path.contains(EQUAL)) {
- addListOrLeafList(path, builder, opTypeForThisNode);
- } else {
- addLeaf(path, builder, opTypeForThisNode);
- }
+ boolean isLastSegment = paths.size() == 1;
- if (isLastNode) {
+ /*
+ * Process the first segment in path.
+ *
+ * BUG ONOS-5500: YMS requires the treatment for the very first
+ * segment in the URI path to be different than the rest. So,
+ * we added a parameter, isFirstIteration, to this function.
+ * It is set to true by the caller when this function is called
+ * the very first time (i.e,, "paths" contains all the segments).
+ *
+ */
+ YdtContextOperationType opTypeForThisSegment = isLastSegment ? opType : NONE;
+ String segment = paths.iterator().next();
+ processSinglePathSegment(segment, builder, opTypeForThisSegment, isFirstIteration);
+
+ if (isLastSegment) {
+ // We have hit the base case of recursion.
return builder;
}
+
+ /*
+ * Chop off the first segment, and recursively process the rest
+ * of the path segments.
+ */
List<String> remainPaths = paths.subList(1, paths.size());
- processPathSegments(remainPaths, builder, opType);
+ processPathSegments(remainPaths, builder, opType, false);
return builder;
}
+ private static void processSinglePathSegment(String pathSegment,
+ YdtBuilder builder,
+ YdtContextOperationType opType,
+ boolean isTopLevelSegment) {
+ if (pathSegment.contains(COLON)) {
+ processPathSegmentWithNamespace(pathSegment, builder, opType, isTopLevelSegment);
+ } else {
+ processPathSegmentWithoutNamespace(pathSegment, builder, opType);
+ }
+ }
+
+ private static void processPathSegmentWithNamespace(String pathSegment,
+ YdtBuilder builder,
+ YdtContextOperationType opType,
+ boolean isTopLevelSegment) {
+ if (isTopLevelSegment) {
+ /*
+ * BUG ONOS-5500: If this segment refers to the first node in
+ * the path (i.e., top level of the model hierarchy), then
+ * YMS requires 2 YDT nodes to be added instead of one. The
+ * first one contains the namespace, and the second contains
+ * the node name. For other segments in the path, only one
+ * YDT node is needed.
+ */
+ addModule(builder, pathSegment);
+ }
+
+ String nodeName = getLatterSegment(pathSegment, COLON);
+ String namespace = getPreSegment(pathSegment, COLON);
+ convertPathSegmentToYdtNode(nodeName, namespace, builder, opType);
+ }
+
+ private static void processPathSegmentWithoutNamespace(String pathSegment,
+ YdtBuilder builder,
+ YdtContextOperationType opType) {
+ convertPathSegmentToYdtNode(pathSegment, null, builder, opType);
+ }
+
+ private static void convertPathSegmentToYdtNode(String pathSegment,
+ String namespace,
+ YdtBuilder builder,
+ YdtContextOperationType opType) {
+ if (pathSegment.contains(EQUAL)) {
+ addListOrLeafList(pathSegment, namespace, builder, opType);
+ } else {
+ addLeaf(pathSegment, namespace, builder, opType);
+ }
+ }
+
private static YdtBuilder addListOrLeafList(String path,
+ String namespace,
YdtBuilder builder,
YdtContextOperationType opType) {
String nodeName = getPreSegment(path, EQUAL);
@@ -155,18 +217,20 @@
if (keyStr.contains(COMMA)) {
List<String> keys = Lists.
newArrayList(COMMA_SPLITTER.split(keyStr));
- builder.addMultiInstanceChild(nodeName, null, keys);
+ builder.addMultiInstanceChild(nodeName, namespace, keys);
} else {
- builder.addMultiInstanceChild(nodeName, null,
+ builder.addMultiInstanceChild(nodeName, namespace,
Lists.newArrayList(keyStr));
}
return builder;
}
- private static YdtBuilder addLeaf(String path, YdtBuilder builder,
+ private static YdtBuilder addLeaf(String path,
+ String namespace,
+ YdtBuilder builder,
YdtContextOperationType opType) {
checkNotNull(path);
- builder.addChild(path, null, opType);
+ builder.addChild(path, namespace, opType);
return builder;
}
diff --git a/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/YdtToJsonListener.java b/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/YdtToJsonListener.java
index b0ce26b..4ffd6f1 100644
--- a/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/YdtToJsonListener.java
+++ b/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/YdtToJsonListener.java
@@ -55,7 +55,7 @@
public void enterYdtNode(YdtContext ydtContext) {
String name = ydtContext.getName();
- if (!isBegin && name.equals(rootName)) {
+ if (!isBegin && name != null && name.equals(rootName)) {
isBegin = true;
}
if (!isBegin) {