[ONOS-6881] Basic uses augment support.
Change-Id: I5d203a531062ab697a0e1d9adc2b9b5ee0fba1c7
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/ResolvableType.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/ResolvableType.java
index 59c8c0b..d7d4059 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/ResolvableType.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/ResolvableType.java
@@ -64,5 +64,10 @@
/**
* Identifies the deviation.
*/
- YANG_DEVIATION
+ YANG_DEVIATION,
+
+ /**
+ * Identifies augment inside uses.
+ */
+ YANG_USES_AUGMENT
}
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
index b58fcf6..934a869 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
@@ -170,25 +170,30 @@
}
@Override
- public void addToChildSchemaMap(
- YangSchemaNodeIdentifier schemaNodeIdentifier,
- YangSchemaNodeContextInfo yangSchemaNodeContextInfo)
- throws DataModelException {
- getYsnContextInfoMap()
- .put(schemaNodeIdentifier, yangSchemaNodeContextInfo);
- YangSchemaNodeContextInfo yangSchemaNodeContextInfo1 =
- new YangSchemaNodeContextInfo();
- yangSchemaNodeContextInfo1
- .setSchemaNode(yangSchemaNodeContextInfo.getSchemaNode());
- yangSchemaNodeContextInfo1.setContextSwitchedNode(this);
- getAugmentedNode().addToChildSchemaMap(schemaNodeIdentifier,
- yangSchemaNodeContextInfo1);
+ public void addToChildSchemaMap(YangSchemaNodeIdentifier schemaNodeIdentifier,
+ YangSchemaNodeContextInfo ctxInfo) throws DataModelException {
+ getYsnContextInfoMap().put(schemaNodeIdentifier, ctxInfo);
+ YangSchemaNodeContextInfo ctxInfo1 = new YangSchemaNodeContextInfo();
+ ctxInfo1.setSchemaNode(ctxInfo.getSchemaNode());
+ ctxInfo1.setContextSwitchedNode(this);
+ if (getAugmentedNode() != null) {
+ if (getAugmentedNode() instanceof YangChoice) {
+ ctxInfo1.setContextSwitchedNode(
+ ctxInfo.getContextSwitchedNode());
+ }
+ getAugmentedNode().addToChildSchemaMap(schemaNodeIdentifier,
+ ctxInfo1);
+ }
}
@Override
public void setNameSpaceAndAddToParentSchemaMap() {
// Get parent namespace and set namespace for self node.
- setNameSpace(getParent().getNameSpace());
+ YangNode parent = getParent();
+ if (parent instanceof YangUses) {
+ parent = parent.getParent();
+ }
+ setNameSpace(parent.getNameSpace());
/*
* Check if node contains leaf/leaf-list, if yes add namespace for leaf
* and leaf list.
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
index 023b816..59ec805 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
@@ -35,6 +35,7 @@
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_IF_FEATURE;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_LEAFREF;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES;
+import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES_AUGMENT;
import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_SINGLE_INSTANCE_NODE;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.linkInterFileReferences;
@@ -242,6 +243,11 @@
private List<YangResolutionInfo> compilerAnnotationList;
/**
+ * Uses-augment resolution list.
+ */
+ private List<YangResolutionInfo> usesAugmentList;
+
+ /**
* Deviation list.
*/
private List<YangResolutionInfo> deviationList;
@@ -317,6 +323,7 @@
notificationEnumMap = new HashMap<>();
augments = new LinkedList<>();
uniqueHolderList = new LinkedList<>();
+ usesAugmentList = new LinkedList<>();
}
@Override
@@ -755,8 +762,10 @@
return unmodifiableList(identityRefResolutionList);
} else if (type == YANG_COMPILER_ANNOTATION) {
return unmodifiableList(compilerAnnotationList);
- } else {
+ } else if (type == YANG_DEVIATION) {
return unmodifiableList(deviationList);
+ } else {
+ return unmodifiableList(usesAugmentList);
}
}
@@ -781,6 +790,8 @@
compilerAnnotationList.add(info);
} else if (type == YANG_DEVIATION) {
deviationList.add(info);
+ } else if (type == YANG_USES_AUGMENT) {
+ usesAugmentList.add(info);
}
}
@@ -805,6 +816,8 @@
compilerAnnotationList = resolutionList;
} else if (type == YANG_DEVIATION) {
deviationList = resolutionList;
+ } else if (type == YANG_USES_AUGMENT) {
+ usesAugmentList = resolutionList;
}
}
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java
index 9940de2..8130e01 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java
@@ -29,6 +29,7 @@
import static org.onosproject.yang.compiler.datamodel.TraversalType.PARENT;
import static org.onosproject.yang.compiler.datamodel.TraversalType.SIBLING;
import static org.onosproject.yang.compiler.datamodel.YangNodeType.RPC_NODE;
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.addUnresolvedAugment;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.cloneListOfLeaf;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.cloneListOfLeafList;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.getParentSchemaContext;
@@ -519,8 +520,12 @@
" at " + nextNodeToClone.getCharPosition() +
" in " + nextNodeToClone.getFileName() + "\"");
}
+
if (curTraversal != PARENT) {
newNode = nextNodeToClone.clone(yangUses, isDeviation);
+ if (newNode instanceof YangUses) {
+ ((YangUses) newNode).setCloned(true);
+ }
detectCollisionWhileCloning(clonedTreeCurNode, newNode,
curTraversal);
}
@@ -548,6 +553,13 @@
clonedTreeCurNode = clonedTreeCurNode.getParent();
}
+ if (curTraversal != PARENT &&
+ clonedTreeCurNode instanceof YangAugment &&
+ (clonedTreeCurNode.getParent() instanceof YangUses)) {
+ YangAugment augment = (YangAugment) clonedTreeCurNode;
+ addUnresolvedAugment(yangUses, augment);
+ }
+
if (curTraversal != PARENT && nextNodeToClone.getChild() != null) {
curTraversal = CHILD;
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
index 3ba193c..61ad3f4 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
@@ -36,6 +36,7 @@
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_IF_FEATURE;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_LEAFREF;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES;
+import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES_AUGMENT;
import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_SINGLE_INSTANCE_NODE;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.linkInterFileReferences;
@@ -241,6 +242,11 @@
private List<YangResolutionInfo> compilerAnnotationList;
/**
+ * Uses-augment resolution list.
+ */
+ private List<YangResolutionInfo> usesAugmentList;
+
+ /**
* Deviation list.
*/
private List<YangResolutionInfo> deviationList;
@@ -320,6 +326,7 @@
notificationEnumMap = new HashMap<>();
augments = new LinkedList<>();
uniqueHolderList = new LinkedList<>();
+ usesAugmentList = new LinkedList<>();
}
@Override
@@ -685,8 +692,10 @@
return unmodifiableList(identityRefResolutionList);
} else if (type == YANG_COMPILER_ANNOTATION) {
return unmodifiableList(compilerAnnotationList);
- } else {
+ } else if (type == YANG_DEVIATION) {
return unmodifiableList(deviationList);
+ } else {
+ return unmodifiableList(usesAugmentList);
}
}
@@ -711,6 +720,8 @@
compilerAnnotationList.add(resolutionInfo);
} else if (type == YANG_DEVIATION) {
deviationList.add(resolutionInfo);
+ } else if (type == YANG_USES_AUGMENT) {
+ usesAugmentList.add(resolutionInfo);
}
}
@@ -735,6 +746,8 @@
compilerAnnotationList = resolutionList;
} else if (type == YANG_DEVIATION) {
deviationList = resolutionList;
+ } else if (type == YANG_USES_AUGMENT) {
+ usesAugmentList = resolutionList;
}
}
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java
index f5df6e2..96c3ba9 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java
@@ -151,6 +151,11 @@
private boolean defaultDenyAll;
/**
+ * Status of cloning of YANG uses.
+ */
+ private boolean isCloned;
+
+ /**
* Creates an YANG uses node.
*/
public YangUses() {
@@ -598,4 +603,22 @@
public void setDefaultDenyAll(boolean defaultDenyAll) {
this.defaultDenyAll = defaultDenyAll;
}
+
+ /**
+ * Returns true if YANG uses is cloned; false otherwise.
+ *
+ * @return true if cloned; false otherwise
+ */
+ public boolean isCloned() {
+ return isCloned;
+ }
+
+ /**
+ * Sets the YANG uses cloned status.
+ *
+ * @param cloned cloned status
+ */
+ public void setCloned(boolean cloned) {
+ isCloned = cloned;
+ }
}
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/DataModelUtils.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/DataModelUtils.java
index c6385cb..390ca67 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/DataModelUtils.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/DataModelUtils.java
@@ -93,7 +93,9 @@
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_IF_FEATURE;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_LEAFREF;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES;
+import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES_AUGMENT;
import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
+import static org.onosproject.yang.compiler.datamodel.utils.ResolvableStatus.UNRESOLVED;
import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.ENUMERATION;
@@ -126,6 +128,8 @@
"cannot be mentioned more than one time in the unique statement";
private static final String E_TARGET_NODE = "YANG file error: The target" +
" node in unique reference path is invalid";
+ private static final String E_DATATREE = "Internal datamodel error: Datam" +
+ "odel tree is not correct";
/**
* Creates a new data model tree utility.
@@ -237,52 +241,48 @@
/**
* Add a resolution information.
*
- * @param resolutionInfo information about the YANG construct which has to be resolved
+ * @param resInfo resolvable YANG info
* @throws DataModelException a violation of data model rules
*/
- public static void addResolutionInfo(YangResolutionInfo resolutionInfo)
+ public static void addResolutionInfo(YangResolutionInfo resInfo)
throws DataModelException {
/* get the module node to add maintain the list of nested reference */
- YangNode curNode = resolutionInfo.getEntityToResolveInfo()
+ YangNode curNode = resInfo.getEntityToResolveInfo()
.getHolderOfEntityToResolve();
while (!(curNode instanceof YangReferenceResolver)) {
curNode = curNode.getParent();
if (curNode == null) {
- throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
+ throw new DataModelException(E_DATATREE);
}
}
- YangReferenceResolver resolutionNode = (YangReferenceResolver) curNode;
- YangEntityToResolveInfo entityToResolveInfo = resolutionInfo.getEntityToResolveInfo();
- if (entityToResolveInfo.getEntityToResolve()
- instanceof YangType) {
- resolutionNode.addToResolutionList(resolutionInfo,
- YANG_DERIVED_DATA_TYPE);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangUses) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_USES);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangAugment) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_AUGMENT);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangIfFeature) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_IF_FEATURE);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangLeafRef) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_LEAFREF);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangBase) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_BASE);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangIdentityRef) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_IDENTITYREF);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangCompilerAnnotation) {
- resolutionNode.addToResolutionList(resolutionInfo,
- YANG_COMPILER_ANNOTATION);
- } else if (entityToResolveInfo.getEntityToResolve()
- instanceof YangDeviation) {
- resolutionNode.addToResolutionList(resolutionInfo, YANG_DEVIATION);
+
+ YangReferenceResolver root = (YangReferenceResolver) curNode;
+ YangEntityToResolveInfo entity = resInfo.getEntityToResolveInfo();
+ Object en = entity.getEntityToResolve();
+
+ if (en instanceof YangType) {
+ root.addToResolutionList(resInfo, YANG_DERIVED_DATA_TYPE);
+ } else if (en instanceof YangUses) {
+ root.addToResolutionList(resInfo, YANG_USES);
+ } else if (en instanceof YangAugment) {
+ if (entity.getHolderOfEntityToResolve() instanceof YangUses) {
+ root.addToResolutionList(resInfo, YANG_USES_AUGMENT);
+ } else {
+ root.addToResolutionList(resInfo, YANG_AUGMENT);
+ }
+ } else if (en instanceof YangIfFeature) {
+ root.addToResolutionList(resInfo, YANG_IF_FEATURE);
+ } else if (en instanceof YangLeafRef) {
+ root.addToResolutionList(resInfo, YANG_LEAFREF);
+ } else if (en instanceof YangBase) {
+ root.addToResolutionList(resInfo, YANG_BASE);
+ } else if (en instanceof YangIdentityRef) {
+ root.addToResolutionList(resInfo, YANG_IDENTITYREF);
+ } else if (en instanceof YangCompilerAnnotation) {
+ root.addToResolutionList(resInfo, YANG_COMPILER_ANNOTATION);
+ } else if (en instanceof YangDeviation) {
+ root.addToResolutionList(resInfo, YANG_DEVIATION);
}
}
@@ -382,17 +382,21 @@
/**
* Returns the contained data model parent node.
*
- * @param currentNode current node which parent contained node is required
+ * @param curNode current node
* @return parent node in which the current node is an attribute
*/
- public static YangNode getParentNodeInGenCode(YangNode currentNode) {
+ public static YangNode getParentNodeInGenCode(YangNode curNode) {
/*
* TODO: recursive parent lookup to support choice/augment/uses. TODO:
* need to check if this needs to be updated for
* choice/case/augment/grouping
*/
- return currentNode.getParent();
+ YangNode parent = curNode.getParent();
+ if (curNode instanceof YangAugment && parent instanceof YangUses) {
+ parent = parent.getParent();
+ }
+ return parent;
}
/**
@@ -456,6 +460,29 @@
}
/**
+ * Adds the resolved augment from the cloned uses.
+ *
+ * @param uses YANG uses
+ * @param aug cloned augment
+ * @throws DataModelException data model error
+ */
+ public static void addUnresolvedAugment(YangUses uses, YangAugment aug)
+ throws DataModelException {
+ if (uses.getCurrentGroupingDepth() == 0) {
+ List<YangEntityToResolveInfoImpl> infoList = new LinkedList<>();
+ YangEntityToResolveInfoImpl info =
+ new YangEntityToResolveInfoImpl<>();
+ aug.setResolvableStatus(UNRESOLVED);
+ info.setEntityToResolve(aug);
+ info = setInformationInEntity(info, aug.getParent(),
+ aug.getCharPosition(),
+ aug.getLineNumber());
+ infoList.add(info);
+ uses.addEntityToResolve(infoList);
+ }
+ }
+
+ /**
* Returns true if collection object is non-null and non-empty; false
* otherwise.
*
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/XpathLinkingTypes.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/XpathLinkingTypes.java
index d8ec27e..602247a 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/XpathLinkingTypes.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/XpathLinkingTypes.java
@@ -30,5 +30,8 @@
COMPILER_ANNOTATION_LINKING,
// Deviation linking.
- DEVIATION_LINKING
+ DEVIATION_LINKING,
+
+ // Uses augment linking
+ USES_AUGMENT_LINKING
}
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java
index 38917ca..743207b 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerManager.java
@@ -38,6 +38,7 @@
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_IF_FEATURE;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_LEAFREF;
import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES;
+import static org.onosproject.yang.compiler.datamodel.ResolvableType.YANG_USES_AUGMENT;
import static org.onosproject.yang.compiler.linker.impl.YangLinkerUtils.updateFilePriority;
import static org.onosproject.yang.compiler.utils.UtilConstants.NEW_LINE;
@@ -186,6 +187,7 @@
yangNode);
resolver.resolveInterFileLinking(YANG_IF_FEATURE);
resolver.resolveInterFileLinking(YANG_USES);
+ resolver.resolveInterFileLinking(YANG_USES_AUGMENT);
resolver.resolveInterFileLinking(YANG_AUGMENT);
resolver.resolveInterFileLinking(YANG_DERIVED_DATA_TYPE);
resolver.resolveInterFileLinking(YANG_BASE);
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerUtils.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerUtils.java
index 6d10652..3607eec 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerUtils.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangLinkerUtils.java
@@ -481,10 +481,11 @@
*
* @param augment instance of YANG augment
* @param remainingAncestors ancestor count to move in augment path
- * @return list of path names needed in leafref
+ * @return list of path names needed in leafref or YANG node
*/
- static List<String> getPathWithAugment(YangAugment augment, int remainingAncestors) {
+ static Object getPathWithAugment(YangAugment augment, int remainingAncestors) {
List<String> listOfPathName = new ArrayList<>();
+ YangNode node = augment.getAugmentedNode();
for (YangAtomicPath atomicPath : augment.getTargetNode()) {
if (atomicPath.getNodeIdentifier().getPrefix() != null &&
!atomicPath.getNodeIdentifier().getPrefix().equals(EMPTY_STRING)) {
@@ -493,14 +494,37 @@
} else {
listOfPathName.add(atomicPath.getNodeIdentifier().getName());
}
+ if (node != null) {
+ node = node.getParent();
+ }
}
for (int countOfAncestor = 0; countOfAncestor < remainingAncestors; countOfAncestor++) {
+ if (listOfPathName.isEmpty()) {
+ return getNodeFromUsesAug(node, remainingAncestors - countOfAncestor);
+ }
listOfPathName.remove(listOfPathName.size() - 1);
}
+ if (listOfPathName.isEmpty()) {
+ return getNodeFromUsesAug(node, 0);
+ }
return listOfPathName;
}
/**
+ * Returns the YANG node from uses augment.
+ *
+ * @param node YANG node
+ * @param count number of ancestors
+ * @return YANG node.
+ */
+ private static YangNode getNodeFromUsesAug(YangNode node, int count) {
+ for (int val = 0; val < count; val++) {
+ node = node.getParent();
+ }
+ return node;
+ }
+
+ /**
* Skips the invalid nodes which cannot have data from YANG.
*
* @param curParent current parent
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java
index 4806aba..220f19a 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangResolutionInfoImpl.java
@@ -1054,8 +1054,9 @@
throws DataModelException {
YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
-
- if (entityToResolve instanceof YangAugment) {
+ YangNode node = entityToResolveInfo.getHolderOfEntityToResolve();
+ if (entityToResolve instanceof YangAugment &&
+ !(node instanceof YangUses)) {
YangNode targetNode;
YangAugment augment = (YangAugment) entityToResolve;
targetNode = xPathLinker
@@ -1166,6 +1167,33 @@
Resolvable resolvable = (Resolvable) entityToResolve;
resolvable.setResolvableStatus(RESOLVED);
+ } else if (entityToResolve instanceof YangAugment) {
+ resolveUsesAugment(entityToResolve, node);
+ }
+ }
+
+ private void resolveUsesAugment(T entity, YangNode node) {
+ YangXpathLinker<T> linker = new YangXpathLinker<T>();
+ YangAugment aug = (YangAugment) entity;
+ YangNode tgt = linker.processUsesAugLinking(aug.getTargetNode(),
+ (YangUses) node);
+ if (tgt != null) {
+ if (tgt instanceof YangAugmentableNode) {
+ //TODO: collision detection
+ ((YangAugmentableNode) tgt).addAugmentation(aug);
+ aug.setAugmentedNode(tgt);
+ setAugmentedFlagInAncestors(tgt);
+ Resolvable resolvable = (Resolvable) entity;
+ resolvable.setResolvableStatus(RESOLVED);
+ if (tgt instanceof YangInput) {
+ linker.addInModuleIfInput(aug, node);
+ }
+ } else {
+ throw new LinkerException(getErrorMsg(
+ INVALID_TARGET + tgt.getNodeType(),
+ aug.getName(), aug.getLineNumber(),
+ aug.getCharPosition(), aug.getFileName()));
+ }
}
}
@@ -1618,8 +1646,8 @@
curParent = skipInvalidDataNodes(curParent, leafref);
if (curParent instanceof YangAugment) {
YangAugment augment = (YangAugment) curParent;
- List<String> valueInAugment = getPathWithAugment(augment,
- ancestorCount - curParentCount);
+ Object valueInAugment = getPathWithAugment(augment,
+ ancestorCount - curParentCount);
return (T) valueInAugment;
} else {
while (curParentCount < ancestorCount) {
@@ -1636,7 +1664,7 @@
curParentCount = curParentCount + 1;
if (curParent instanceof YangAugment) {
YangAugment augment = (YangAugment) curParent;
- List<String> valueInAugment = getPathWithAugment(
+ Object valueInAugment = getPathWithAugment(
augment, ancestorCount - curParentCount);
return (T) valueInAugment;
}
diff --git a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangXpathLinker.java b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangXpathLinker.java
index e4d2d97..1223d20 100644
--- a/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangXpathLinker.java
+++ b/compiler/base/linker/src/main/java/org/onosproject/yang/compiler/linker/impl/YangXpathLinker.java
@@ -40,6 +40,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -51,6 +52,7 @@
import static org.onosproject.yang.compiler.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTER;
import static org.onosproject.yang.compiler.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTRA;
import static org.onosproject.yang.compiler.linker.impl.XpathLinkingTypes.AUGMENT_LINKING;
+import static org.onosproject.yang.compiler.linker.impl.XpathLinkingTypes.USES_AUGMENT_LINKING;
import static org.onosproject.yang.compiler.utils.UtilConstants.COLON;
import static org.onosproject.yang.compiler.utils.UtilConstants.ERROR_MSG_FOR_AUGMENT_LINKING;
import static org.onosproject.yang.compiler.utils.UtilConstants.FAILED_TO_FIND_LEAD_INFO_HOLDER;
@@ -218,6 +220,21 @@
}
/**
+ * Processes uses augment linking.
+ *
+ * @param paths YANG atomic path list
+ * @param uses YANG uses
+ * @return augmented node
+ */
+ public YangNode processUsesAugLinking(List<YangAtomicPath> paths,
+ YangUses uses) {
+ absPaths = paths;
+ rootNode = uses;
+ linkingType = USES_AUGMENT_LINKING;
+ return parseUsesAugData(uses.getParent());
+ }
+
+ /**
* Searches for the referred leaf in target node.
*
* @param targetNode target node
@@ -338,6 +355,121 @@
}
/**
+ * Parses uses-augment data to finding the augmented node.
+ *
+ * @param node YANG uses parent
+ * @return augmented node
+ */
+ private YangNode parseUsesAugData(YangNode node) {
+ YangNode temp = node;
+ YangNode tgt;
+ Iterator<YangAtomicPath> it = absPaths.iterator();
+ YangAtomicPath path;
+ YangNodeIdentifier id;
+ StringBuilder builder = new StringBuilder();
+ while (it.hasNext()) {
+ path = it.next();
+ id = path.getNodeIdentifier();
+ tgt = searchTargetNode(temp, id);
+ if (tgt == null) {
+ temp = getAugmentNode(temp, builder.toString());
+ if (temp != null) {
+ tgt = searchTargetNode(temp, id);
+ }
+ }
+ temp = tgt;
+ builder.append(id.getName());
+ builder.append("/");
+ }
+ return temp;
+ }
+
+ /**
+ * Returns the augment node, that contains the node to be searched.
+ *
+ * @param temp parent YANG node
+ * @param id node id to be searched
+ * @return YANG augment node
+ */
+ private YangAugment getAugmentNode(YangNode temp, String id) {
+ String augId = getAugNodeId(id);
+ YangNode parent = temp.getParent();
+ List<YangUses> usesList = getUsesNode(parent);
+ for (YangUses uses : usesList) {
+ List<YangAugment> augList = getAugList(uses);
+ if (!augList.isEmpty()) {
+ for (YangAugment aug : augList) {
+ if (aug.getPrefixRemovedName().equals(augId)) {
+ return aug;
+ }
+ }
+ }
+ }
+ // TODO: Has to be more specific error message.
+ throw new LinkerException("Invalid augment path");
+ }
+
+ /**
+ * Gets the list of augments from the uses.
+ *
+ * @param uses YANG uses
+ * @return list of YANG augment
+ */
+ private List<YangAugment> getAugList(YangUses uses) {
+ List<YangAugment> augList = new LinkedList<>();
+ YangNode child = uses.getChild();
+ while (child != null) {
+ if (child instanceof YangAugment) {
+ augList.add((YangAugment) child);
+ }
+ child = child.getNextSibling();
+ }
+ return augList;
+ }
+
+ /**
+ * Returns a proper YANG augment id to be searched.
+ *
+ * @param id YANG augment id
+ * @return formatted id
+ */
+ private String getAugNodeId(String id) {
+ int ind = id.indexOf(SLASH_FOR_STRING);
+ try {
+ id = id.substring(ind + 1, id.length() - 1);
+ } catch (StringIndexOutOfBoundsException e) {
+ throw new LinkerException("Invalid augment path");
+ }
+ StringBuilder str = new StringBuilder();
+ String[] arr;
+
+ arr = id.split(SLASH_FOR_STRING);
+ for (String a : arr) {
+ str.append(SLASH_FOR_STRING);
+ str.append(a);
+ }
+ return str.toString();
+ }
+
+ /**
+ * Returns the YANG uses node list.
+ *
+ * @param node parent node
+ * @return YANG uses list
+ */
+ private List<YangUses> getUsesNode(YangNode node) {
+ YangNode curNode = node.getChild();
+ List<YangUses> usesList = new LinkedList<>();
+ while (curNode != null) {
+ if (curNode instanceof YangUses) {
+ usesList.add((YangUses) curNode);
+ }
+ curNode = curNode.getNextSibling();
+ }
+ return usesList;
+ }
+
+ /**
* Validates temp path nodes for augment linking.
*
* @param node temp path node
@@ -396,8 +528,8 @@
* Resolves inter file augment linking.
*
* @param tempPath temporary absolute path
- * @param root root node
- * @param size node size
+ * @param root root node
+ * @param size node size
* @return linked target node
*/
private YangNode resolveInterFileAugment(YangAtomicPath tempPath,
diff --git a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
index 62595fa..4f77d69 100644
--- a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
+++ b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
@@ -51,6 +51,7 @@
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.getPrefixRemovedName;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.getValidAbsoluteSchemaNodeId;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.parseUsesAugment;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerValidation.validateCardinalityEitherOne;
@@ -106,23 +107,22 @@
Parsable curData = listener.getParsedDataStack().peek();
- if (curData instanceof YangUses) {
- throw new ParserException(constructListenerErrorMessage(
- UNHANDLED_PARSED_DATA, AUGMENT_DATA,
- ctx.augment().getText(), ENTRY));
- }
-
if (!(curData instanceof YangModule) &&
- !(curData instanceof YangSubModule)) {
+ !(curData instanceof YangSubModule) &&
+ !(curData instanceof YangUses)) {
throw new ParserException(constructListenerErrorMessage(
INVALID_HOLDER, AUGMENT_DATA,
ctx.augment().getText(), ENTRY));
}
+ List<YangAtomicPath> atomics;
- // Validates augment argument string
- List<YangAtomicPath> atomics =
- getValidAbsoluteSchemaNodeId(ctx.augment().getText(),
- AUGMENT_DATA, ctx);
+ if (curData instanceof YangUses) {
+ atomics = parseUsesAugment((YangNode) curData, ctx);
+ } else {
+ atomics = getValidAbsoluteSchemaNodeId(ctx.augment().getText(),
+ AUGMENT_DATA, ctx);
+ }
+
valSubStatCardinality(ctx);
int line = ctx.getStart().getLine();
diff --git a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
index 0701f28..aaadaf2 100644
--- a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
+++ b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
@@ -30,6 +30,7 @@
import org.onosproject.yang.compiler.datamodel.YangSubModule;
import org.onosproject.yang.compiler.datamodel.YangUniqueHolder;
import org.onosproject.yang.compiler.datamodel.utils.YangConstructType;
+import org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.AugmentStatementContext;
import org.onosproject.yang.compiler.parser.exceptions.ParserException;
import org.slf4j.Logger;
@@ -45,6 +46,7 @@
import java.util.regex.Pattern;
import static org.onosproject.yang.compiler.datamodel.YangPathOperator.EQUALTO;
+import static org.onosproject.yang.compiler.datamodel.utils.YangConstructType.AUGMENT_DATA;
import static org.onosproject.yang.compiler.datamodel.utils.YangConstructType.UNIQUE_DATA;
import static org.onosproject.yang.compiler.datamodel.utils.YangConstructType.getYangConstructType;
import static org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
@@ -75,8 +77,11 @@
* Represents an utility for listener.
*/
public final class ListenerUtil {
+ public static final String SPACE = " ";
+ public static final String LINE_NUMBER = "line number ";
+ public static final String CHARACTER_POSITION = "character position ";
+ public static final String FILE = "file ";
private static final Logger log = getLogger(ListenerUtil.class);
-
private static final Pattern IDENTIFIER_PATTERN =
Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
private static final String DATE_PATTERN =
@@ -92,12 +97,11 @@
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String REGEX_EQUAL = "[=]";
private static final String REGEX_OPEN_BRACE = "[(]";
- public static final String SPACE = " ";
- public static final String LINE_NUMBER = "line number ";
- public static final String CHARACTER_POSITION = "character position ";
- public static final String FILE = "file ";
- private static final String E_LEAF_REF = "YANG file error : A leaf " +
- "reference, in unique, must refer to a leaf in the list";
+ private static final String E_DES_NODE = "YANG file error : The " +
+ "reference path of descendant schema is not pointing to node " +
+ "inside itself";
+ private static final String E_DES_FORMAT = "YANG file error : The " +
+ "descendant path must not start with a slash(/)";
// No instantiation.
private ListenerUtil() {
@@ -432,27 +436,50 @@
}
/**
- * Validates the unique syntax from the reference path.
+ * Parses the uses augment statement, validates the statement and creates
+ * a list of YANG atomic path.
*
- * @param val path of unique
- * @param prefix current file's prefix
- * @param ctx yang construct's context to get the line number and character position
- * @return list of absolute path
+ * @param uses YANG uses
+ * @param ctx YANG construct
+ * @return YANG atomic path list
*/
- private static List<YangAtomicPath> validateUniqueValues(String val,
- String prefix,
- ParserRuleContext ctx) {
+ public static List<YangAtomicPath> parseUsesAugment(YangNode uses,
+ AugmentStatementContext ctx) {
+ String val = removeQuotesAndHandleConcat(ctx.augment().getText());
+ String rootPre = getRootPrefix(uses);
+ return validateDesSchemaNode(val, rootPre, ctx, AUGMENT_DATA);
+ }
+
+ /**
+ * Validates the descendant schema node id, after parsing, by converting
+ * it to YANG atomic path.
+ *
+ * @param val descendant schema
+ * @param prefix current file's prefix
+ * @param ctx yang construct
+ * @param type YANG construct type
+ * @return list of YANG atomic path
+ */
+ private static List<YangAtomicPath> validateDesSchemaNode(String val,
+ String prefix,
+ ParserRuleContext ctx,
+ YangConstructType type) {
+ if (val.startsWith(SLASH_FOR_STRING)) {
+ ParserException exc = new ParserException(E_DES_FORMAT);
+ exc.setLine(ctx.getStart().getLine());
+ exc.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw exc;
+ }
List<YangAtomicPath> pathList = new LinkedList<>();
String[] path = val.split(SLASH_FOR_STRING);
for (String uniVal : path) {
YangAtomicPath atomicPath = new YangAtomicPath();
- YangNodeIdentifier nodeId = getValidNodeIdentifier(
- uniVal, UNIQUE_DATA, ctx);
- atomicPath.setNodeIdentifier(nodeId);
+ YangNodeIdentifier id = getValidNodeIdentifier(uniVal, type, ctx);
+ atomicPath.setNodeIdentifier(id);
pathList.add(atomicPath);
- if (nodeId.getPrefix() != null &&
- !nodeId.getPrefix().equals(prefix)) {
- ParserException exc = new ParserException(E_LEAF_REF);
+ if (id.getPrefix() != null &&
+ !id.getPrefix().equals(prefix)) {
+ ParserException exc = new ParserException(E_DES_NODE);
exc.setLine(ctx.getStart().getLine());
exc.setCharPosition(ctx.getStart().getCharPositionInLine());
throw exc;
@@ -461,6 +488,11 @@
return pathList;
}
+ /**
+ * Adds the unique holder to the module or sub-module node.
+ *
+ * @param holder unique holder
+ */
public static void addUniqueHolderToRoot(YangUniqueHolder holder) {
List<List<YangAtomicPath>> uniques = holder.getPathList();
if (uniques != null && !uniques.isEmpty()) {
@@ -483,7 +515,7 @@
ParserRuleContext ctx) {
YangNode node = (YangNode) holder;
String rootPre = getRootPrefix(node);
- return validateUniqueValues(val, rootPre, ctx);
+ return validateDesSchemaNode(val, rootPre, ctx, UNIQUE_DATA);
}
/**
diff --git a/compiler/base/parser/src/test/java/org/onosproject/yang/compiler/parser/impl/listeners/UniqueListenerTest.java b/compiler/base/parser/src/test/java/org/onosproject/yang/compiler/parser/impl/listeners/UniqueListenerTest.java
index 1e9bbda..3eb460b 100644
--- a/compiler/base/parser/src/test/java/org/onosproject/yang/compiler/parser/impl/listeners/UniqueListenerTest.java
+++ b/compiler/base/parser/src/test/java/org/onosproject/yang/compiler/parser/impl/listeners/UniqueListenerTest.java
@@ -156,8 +156,8 @@
public void processParsingUniqueDescendent() throws IOException,
ParserException {
thrown.expect(ParserException.class);
- thrown.expectMessage("YANG file error : unique name is" +
- " not valid.");
+ thrown.expectMessage("YANG file error : The descendant path must not" +
+ " start with a slash(/)");
YangNode node = manager.getDataModel(
"src/test/resources/UniqueDescendent.yang");
}
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/JavaCodeGeneratorUtil.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/JavaCodeGeneratorUtil.java
index 10c4b6f..8a02940 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/JavaCodeGeneratorUtil.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/JavaCodeGeneratorUtil.java
@@ -19,6 +19,7 @@
import org.onosproject.yang.compiler.datamodel.RpcNotificationContainer;
import org.onosproject.yang.compiler.datamodel.SchemaDataNode;
import org.onosproject.yang.compiler.datamodel.TraversalType;
+import org.onosproject.yang.compiler.datamodel.YangAugment;
import org.onosproject.yang.compiler.datamodel.YangInput;
import org.onosproject.yang.compiler.datamodel.YangLeavesHolder;
import org.onosproject.yang.compiler.datamodel.YangNode;
@@ -78,12 +79,11 @@
codeGenNode.getFileName());
}
try {
- if (codeGen) {
- generateCodeEntry(codeGenNode, yangPlugin, rootNode);
- } else {
- //for uses java info is not required so need to skip
- // it and go to its sibling or parent node.
- if (!(codeGenNode instanceof YangUses)) {
+ if (!(codeGenNode instanceof YangUses) ||
+ !((YangUses) codeGenNode).isCloned()) {
+ if (codeGen) {
+ generateCodeEntry(codeGenNode, yangPlugin, rootNode);
+ } else {
//this will update java file info for the target
// node.
updateJavaInfo(codeGenNode, yangPlugin);
@@ -95,22 +95,27 @@
((RpcNotificationContainer) codeGenNode.getParent())
.addToNotificationEnumMap(enumName, codeGenNode);
}
- } else {
- //handle uses ,its java info is not required.
- if (codeGenNode.getNextSibling() != null) {
- curTraversal = SIBLING;
- codeGenNode = codeGenNode.getNextSibling();
- } else {
- curTraversal = PARENT;
- codeGenNode = codeGenNode.getParent();
- }
- continue;
}
- }
- codeGenNode.setNameSpaceAndAddToParentSchemaMap();
- if (codeGenNode instanceof YangLeavesHolder ||
- codeGenNode instanceof SchemaDataNode) {
- codeGenNode.setParentContext();
+ if (!(codeGenNode instanceof YangUses)) {
+ codeGenNode.setNameSpaceAndAddToParentSchemaMap();
+ if (codeGenNode instanceof YangLeavesHolder ||
+ codeGenNode instanceof SchemaDataNode) {
+ codeGenNode.setParentContext();
+ }
+ }
+ } else {
+ if (((YangUses) codeGenNode).isCloned()) {
+ setUsesAugNsAddToParent((YangUses) codeGenNode);
+ }
+ //handle uses ,its java info is not required.
+ if (codeGenNode.getNextSibling() != null) {
+ curTraversal = SIBLING;
+ codeGenNode = codeGenNode.getNextSibling();
+ } else {
+ curTraversal = PARENT;
+ codeGenNode = codeGenNode.getParent();
+ }
+ continue;
}
} catch (InvalidNodeForTranslatorException e) {
if (codeGenNode.getNextSibling() != null) {
@@ -376,4 +381,52 @@
}
return null;
}
+
+ /**
+ * Sets the uses augment and its child's namespace and adds it to the
+ * parent.
+ *
+ * @param uses YANG uses
+ */
+ public static void setUsesAugNsAddToParent(YangUses uses) {
+ YangNode node = uses.getChild();
+ while (node != null) {
+ if (node instanceof YangAugment) {
+ node.setNameSpaceAndAddToParentSchemaMap();
+ node.setParentContext();
+ processAugNode((YangAugment) node);
+ }
+ node = node.getNextSibling();
+ }
+ }
+
+ /**
+ * Processes the YANG augment node and its complete tree.
+ *
+ * @param aug YANG augment
+ */
+ private static void processAugNode(YangAugment aug) {
+ YangNode child = aug.getChild();
+ TraversalType curTraversal = ROOT;
+
+ while (child != aug && child != null) {
+ if (curTraversal != PARENT) {
+ child.setNameSpaceAndAddToParentSchemaMap();
+ if (child instanceof YangLeavesHolder ||
+ child instanceof SchemaDataNode) {
+ child.setParentContext();
+ }
+ }
+ if (curTraversal != PARENT && child.getChild() != null) {
+ curTraversal = CHILD;
+ child = child.getChild();
+ } else if (child.getNextSibling() != null) {
+ curTraversal = SIBLING;
+ child = child.getNextSibling();
+ } else {
+ curTraversal = PARENT;
+ child = child.getParent();
+ }
+ }
+ }
}
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/TempJavaFragmentFiles.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/TempJavaFragmentFiles.java
index 931f3d9..231675e 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/TempJavaFragmentFiles.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/TempJavaFragmentFiles.java
@@ -27,6 +27,7 @@
import org.onosproject.yang.compiler.datamodel.YangNode;
import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
import org.onosproject.yang.compiler.datamodel.YangType;
+import org.onosproject.yang.compiler.datamodel.YangUses;
import org.onosproject.yang.compiler.datamodel.javadatamodel.JavaFileInfo;
import org.onosproject.yang.compiler.datamodel.javadatamodel.JavaQualifiedTypeInfo;
import org.onosproject.yang.compiler.translator.exception.TranslatorException;
@@ -1675,6 +1676,9 @@
//Removes case's parent import.
private void removeCaseParentImport(YangNode node, List<String> imports) {
YangNode parent = node.getParent();
+ if (parent instanceof YangUses) {
+ parent = parent.getParent();
+ }
JavaFileInfo info = ((JavaFileInfoContainer) parent).getJavaFileInfo();
String impt = getImportString(info.getPackage(),
getCapitalCase(info.getJavaName()));
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/YangJavaModelUtils.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/YangJavaModelUtils.java
index 8b97d1a..a8e27d0 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/YangJavaModelUtils.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/YangJavaModelUtils.java
@@ -603,6 +603,9 @@
YangPluginConfig config) {
List<String> clsInfo = new ArrayList<>();
+ if (node.getReferredSchema() != null) {
+ node = (YangNode) node.getReferredSchema();
+ }
while (node.getParent() != null) {
if (node instanceof YangJavaAugmentTranslator) {
YangJavaAugmentTranslator augment =
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaUsesTranslator.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaUsesTranslator.java
index a1d966f..8821d10 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaUsesTranslator.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaUsesTranslator.java
@@ -16,7 +16,6 @@
package org.onosproject.yang.compiler.translator.tojava.javamodel;
import org.onosproject.yang.compiler.datamodel.javadatamodel.YangJavaUses;
-import org.onosproject.yang.compiler.translator.exception.InvalidNodeForTranslatorException;
import org.onosproject.yang.compiler.translator.exception.TranslatorException;
import org.onosproject.yang.compiler.translator.tojava.JavaCodeGenerator;
import org.onosproject.yang.compiler.translator.tojava.JavaCodeGeneratorInfo;
@@ -96,11 +95,9 @@
@Override
public void generateCodeEntry(YangPluginConfig yangPlugin)
throws TranslatorException {
- InvalidNodeForTranslatorException exception = new InvalidNodeForTranslatorException();
- exception.setFileName(this.getFileName());
- exception.setCharPosition(this.getCharPosition());
- exception.setLine(this.getLineNumber());
- throw exception;
+ /*
+ * Do nothing.
+ */
}
@Override
diff --git a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/UsesAugmentLinkingTest.java b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/UsesAugmentLinkingTest.java
new file mode 100644
index 0000000..5e035e0
--- /dev/null
+++ b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/UsesAugmentLinkingTest.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+package org.onosproject.yang.compiler.plugin.maven;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.junit.Test;
+import org.onosproject.yang.compiler.datamodel.YangAugment;
+import org.onosproject.yang.compiler.datamodel.YangAugmentableNode;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.utils.ResolvableStatus;
+import org.onosproject.yang.compiler.parser.exceptions.ParserException;
+import org.onosproject.yang.compiler.tool.YangCompilerManager;
+import org.onosproject.yang.compiler.utils.io.YangPluginConfig;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static java.lang.System.getProperty;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yang.compiler.datamodel.utils.ResolvableStatus.RESOLVED;
+import static org.onosproject.yang.compiler.utils.io.impl.YangFileScanner.getYangFiles;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit test case for uses augment linker and translator.
+ */
+public class UsesAugmentLinkingTest {
+
+ private static final String DIR = "target/usesaugment/";
+ private static final String COMP = getProperty("user.dir") +
+ File.separator + DIR;
+ private final YangCompilerManager utilMgr = new YangCompilerManager();
+ private final String path = "src/test/resources/usesaugment/";
+
+ /**
+ * Processes a simple uses augment linker.
+ *
+ * @throws IOException if IO exception occurs
+ */
+ @Test
+ public void processSimpleUsesAug() throws IOException {
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(path + "simpleusesaug/")) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangNode node = utilMgr.getYangNodeSet().iterator().next();
+
+ YangNode cont1 = node.getChild();
+ YangNode groupUses = cont1.getChild();
+ YangNode cont2aug = groupUses.getChild();
+ assertThat(cont2aug instanceof YangAugment, is(true));
+
+ YangAugment aug1 = (YangAugment) cont2aug;
+ ResolvableStatus status = aug1.getResolvableStatus();
+ assertThat(status, is(RESOLVED));
+ YangNode target = aug1.getAugmentedNode();
+
+ YangNode cont2 = groupUses.getNextSibling();
+ List<YangAugment> augList = ((YangAugmentableNode) cont2)
+ .getAugmentedInfoList();
+
+ assertThat(augList.get(0), is(aug1));
+ assertThat(cont2, is(target));
+ }
+
+ /**
+ * Processes multiple uses augment linker.
+ *
+ * @throws IOException if IO exception occurs
+ */
+ @Test
+ public void processMultiUsesAug() throws IOException {
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(path + "multiusesaug/")) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangNode node = utilMgr.getYangNodeSet().iterator().next();
+
+ YangNode cont1 = node.getChild();
+ YangNode groupUses = cont1.getChild();
+ YangNode cont6aug = groupUses.getChild();
+ assertThat(cont6aug instanceof YangAugment, is(true));
+
+ YangAugment aug1 = (YangAugment) cont6aug;
+ ResolvableStatus status = aug1.getResolvableStatus();
+ assertThat(status, is(RESOLVED));
+ YangNode target = aug1.getAugmentedNode();
+
+ YangNode cont2 = groupUses.getNextSibling();
+ YangNode group2Uses = cont2.getChild();
+ YangNode cont3aug = group2Uses.getChild();
+ assertThat(cont3aug instanceof YangAugment, is(true));
+
+ YangAugment aug2 = (YangAugment) cont3aug;
+ ResolvableStatus status2 = aug2.getResolvableStatus();
+ assertThat(status2, is(RESOLVED));
+ YangNode target2 = aug2.getAugmentedNode();
+
+ YangNode cont3 = group2Uses.getNextSibling();
+ List<YangAugment> augList = ((YangAugmentableNode) cont3)
+ .getAugmentedInfoList();
+ assertThat(augList.get(0), is(aug2));
+ assertThat(cont3, is(target2));
+
+ YangNode cont4 = aug2.getChild();
+ YangNode cont5 = cont4.getChild();
+ YangNode group3uses = cont5.getChild();
+ YangNode cont6 = group3uses.getNextSibling();
+ YangNode cont6aug2 = group3uses.getChild();
+
+ assertThat(cont6aug2 instanceof YangAugment, is(true));
+ YangAugment aug3 = (YangAugment) cont6aug2;
+ ResolvableStatus status3 = aug3.getResolvableStatus();
+ assertThat(status3, is(RESOLVED));
+ YangNode target3 = aug3.getAugmentedNode();
+
+ List<YangAugment> augList1 = ((YangAugmentableNode) cont6)
+ .getAugmentedInfoList();
+ assertThat(augList1.get(0), is(aug1));
+ assertThat(cont6, is(target));
+
+ assertThat(augList1.get(1), is(cont6aug2));
+ assertThat(cont6, is(target3));
+ }
+
+ /**
+ * Processes the inter file uses augment linker.
+ *
+ * @throws IOException if IO exception occurs
+ */
+ @Test
+ public void processInterFileUsesAug() throws IOException {
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(path + "interfileusesaug/")) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangNode selfNode = null;
+ for (YangNode rootNode : utilMgr.getYangNodeSet()) {
+ if (rootNode.getName().equals("module1")) {
+ selfNode = rootNode;
+ }
+ }
+ YangNode not = selfNode.getChild();
+ YangNode groupUses = not.getChild();
+ YangNode cont6aug = groupUses.getChild();
+ assertThat(cont6aug instanceof YangAugment, is(true));
+
+ YangAugment aug1 = (YangAugment) cont6aug;
+ ResolvableStatus status = aug1.getResolvableStatus();
+ assertThat(status, is(RESOLVED));
+ YangNode target = aug1.getAugmentedNode();
+
+ YangNode cont2 = groupUses.getNextSibling().getNextSibling();
+ YangNode group2Uses = cont2.getChild();
+ YangNode cont3aug = group2Uses.getChild();
+ assertThat(cont3aug instanceof YangAugment, is(true));
+
+ YangAugment aug2 = (YangAugment) cont3aug;
+ ResolvableStatus status2 = aug2.getResolvableStatus();
+ assertThat(status2, is(RESOLVED));
+ YangNode target2 = aug2.getAugmentedNode();
+
+ YangNode intaug = aug2.getNextSibling();
+ assertThat(intaug instanceof YangAugment, is(true));
+
+ YangAugment aug3 = (YangAugment) intaug;
+ ResolvableStatus status3 = aug3.getResolvableStatus();
+ assertThat(status3, is(RESOLVED));
+ YangNode target3 = aug3.getAugmentedNode();
+
+ YangNode phyAug = aug3.getNextSibling();
+ assertThat(phyAug instanceof YangAugment, is(true));
+
+ YangAugment aug4 = (YangAugment) phyAug;
+ ResolvableStatus status4 = aug4.getResolvableStatus();
+ assertThat(status4, is(RESOLVED));
+ YangNode target4 = aug4.getAugmentedNode();
+
+ YangNode cont3 = group2Uses.getNextSibling();
+ List<YangAugment> augList = ((YangAugmentableNode) cont3)
+ .getAugmentedInfoList();
+ assertThat(augList.get(0), is(aug2));
+ assertThat(cont3, is(target2));
+
+ YangNode intChoice = cont3.getNextSibling();
+ List<YangAugment> augList2 = ((YangAugmentableNode) intChoice)
+ .getAugmentedInfoList();
+ assertThat(augList2.get(0), is(aug3));
+ assertThat(intChoice, is(target3));
+
+ YangNode phy = intChoice.getChild();
+ List<YangAugment> augList3 = ((YangAugmentableNode) phy)
+ .getAugmentedInfoList();
+ assertThat(augList3.get(0), is(aug4));
+ assertThat(phy, is(target4));
+
+ YangNode cont4 = aug2.getChild();
+ YangNode cont5 = cont4.getChild();
+ YangNode group3uses = cont5.getChild();
+ YangNode cont6 = group3uses.getNextSibling();
+ YangNode cont6aug2 = group3uses.getChild();
+
+ assertThat(cont6aug2 instanceof YangAugment, is(true));
+ YangAugment aug5 = (YangAugment) cont6aug2;
+ ResolvableStatus status5 = aug5.getResolvableStatus();
+ assertThat(status5, is(RESOLVED));
+ YangNode target5 = aug5.getAugmentedNode();
+
+ List<YangAugment> augList5 = ((YangAugmentableNode) cont6)
+ .getAugmentedInfoList();
+ assertThat(augList5.get(0), is(aug1));
+ assertThat(cont6, is(target));
+
+ assertThat(augList5.get(1), is(cont6aug2));
+ assertThat(cont6, is(target5));
+ }
+
+ /**
+ * Processes uses augment with typedef.
+ *
+ * @throws IOException if IO exception occurs
+ */
+ @Test
+ public void processTypedefInUsesAug() throws IOException {
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(path + "typedef/")) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangNode selfNode = null;
+ for (YangNode rootNode : utilMgr.getYangNodeSet()) {
+ if (rootNode.getName().equals("subscription")) {
+ selfNode = rootNode;
+ }
+ }
+
+ YangNode rpc = selfNode.getChild();
+ YangNode in = rpc.getChild();
+ YangNode usesSubPol = in.getChild();
+ YangNode usesSubPolNm = usesSubPol.getNextSibling();
+ YangNode event = usesSubPolNm.getChild();
+
+ assertThat(event instanceof YangAugment, is(true));
+ YangAugment aug1 = (YangAugment) event;
+ ResolvableStatus status1 = aug1.getResolvableStatus();
+ assertThat(status1, is(RESOLVED));
+ YangNode target1 = aug1.getAugmentedNode();
+
+ YangNode targetCh = usesSubPolNm.getNextSibling();
+ YangNode eventCase = targetCh.getChild();
+
+ List<YangAugment> augList1 = ((YangAugmentableNode) eventCase)
+ .getAugmentedInfoList();
+ assertThat(augList1.get(0), is(aug1));
+ assertThat(eventCase, is(target1));
+
+ YangNode out = in.getNextSibling();
+ YangNode usesSubRes = out.getChild();
+ YangNode result = usesSubRes.getChild();
+
+ assertThat(result instanceof YangAugment, is(true));
+ YangAugment aug2 = (YangAugment) result;
+ ResolvableStatus status2 = aug2.getResolvableStatus();
+ assertThat(status2, is(RESOLVED));
+ YangNode target2 = aug2.getAugmentedNode();
+
+ YangNode noSuccess = result.getNextSibling();
+
+ assertThat(noSuccess instanceof YangAugment, is(true));
+ YangAugment aug3 = (YangAugment) noSuccess;
+ ResolvableStatus status3 = aug3.getResolvableStatus();
+ assertThat(status3, is(RESOLVED));
+ YangNode target3 = aug3.getAugmentedNode();
+
+ YangNode resultCh = usesSubRes.getNextSibling();
+
+ List<YangAugment> augList2 = ((YangAugmentableNode) resultCh)
+ .getAugmentedInfoList();
+ assertThat(augList2.get(0), is(aug2));
+ assertThat(resultCh, is(target2));
+
+ YangNode noSuccessCase = resultCh.getChild();
+
+ List<YangAugment> augList3 = ((YangAugmentableNode) noSuccessCase)
+ .getAugmentedInfoList();
+ assertThat(augList3.get(0), is(aug3));
+ assertThat(noSuccessCase, is(target3));
+
+ YangNode subs = rpc.getNextSibling();
+ YangNode usesRec = subs.getChild().getChild().getNextSibling()
+ .getNextSibling();
+ YangNode reciever = usesRec.getChild();
+
+ assertThat(reciever instanceof YangAugment, is(true));
+ YangAugment aug4 = (YangAugment) reciever;
+ ResolvableStatus status4 = aug4.getResolvableStatus();
+ assertThat(status4, is(RESOLVED));
+ YangNode target4 = aug4.getAugmentedNode();
+
+ YangNode recievers = usesRec.getNextSibling().getNextSibling()
+ .getNextSibling().getNextSibling();
+ YangNode recieverList = recievers.getChild();
+
+ List<YangAugment> augList4 = ((YangAugmentableNode) recieverList)
+ .getAugmentedInfoList();
+ assertThat(augList4.get(0), is(aug4));
+ assertThat(recieverList, is(target4));
+ }
+
+ /**
+ * Processes simple uses augment translator.
+ *
+ * @throws IOException if IO exception occurs
+ * @throws ParserException if parser exception occurs
+ * @throws MojoExecutionException if mojo execution exception occurs
+ */
+ @Test
+ public void processSimpleUsesTranslator() throws IOException,
+ ParserException, MojoExecutionException {
+ deleteDirectory(DIR);
+ String searchDir = path + "simpleusesaug/";
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(searchDir)) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangPluginConfig config = new YangPluginConfig();
+ config.setCodeGenDir(DIR);
+ utilMgr.translateToJava(config);
+ YangPluginConfig.compileCode(COMP);
+ deleteDirectory(DIR);
+ }
+
+ /**
+ * Processes multiple uses augment translator.
+ *
+ * @throws IOException if IO exception occurs
+ * @throws ParserException if parser exception occurs
+ * @throws MojoExecutionException if mojo execution exception occurs
+ */
+ @Test
+ public void processMultiUsesTranslator() throws IOException,
+ ParserException,
+ MojoExecutionException {
+ deleteDirectory(DIR);
+ String searchDir = path + "multiusesaug/";
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(searchDir)) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangPluginConfig config = new YangPluginConfig();
+ config.setCodeGenDir(DIR);
+ utilMgr.translateToJava(config);
+ YangPluginConfig.compileCode(COMP);
+ deleteDirectory(DIR);
+ }
+
+ /**
+ * Processes inter uses augment translator.
+ *
+ * @throws IOException if IO exception occurs
+ * @throws ParserException if parser exception occurs
+ * @throws MojoExecutionException if mojo execution exception occurs
+ */
+ @Test
+ public void processInterFileUsesTranslator() throws IOException,
+ ParserException, MojoExecutionException {
+ deleteDirectory(DIR);
+ String searchDir = path + "interfileusesaug/";
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(searchDir)) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangPluginConfig config = new YangPluginConfig();
+ config.setCodeGenDir(DIR);
+ utilMgr.translateToJava(config);
+ YangPluginConfig.compileCode(COMP);
+ deleteDirectory(DIR);
+ }
+
+ /**
+ * Processes typedef uses augment translator.
+ *
+ * @throws IOException if IO exception occurs
+ * @throws ParserException if parser exception occurs
+ * @throws MojoExecutionException if mojo execution exception occurs
+ */
+ @Test
+ public void processTypedefUsesTranslator() throws IOException,
+ ParserException, MojoExecutionException {
+ deleteDirectory(DIR);
+ String searchDir = path + "typedef/";
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(searchDir)) {
+ paths.add(Paths.get(file));
+ }
+
+ utilMgr.createYangFileInfoSet(paths);
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ utilMgr.resolveDependenciesUsingLinker();
+
+ YangPluginConfig config = new YangPluginConfig();
+ config.setCodeGenDir(DIR);
+ utilMgr.translateToJava(config);
+ YangPluginConfig.compileCode(COMP);
+ deleteDirectory(DIR);
+ }
+}
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module1.yang b/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module1.yang
new file mode 100644
index 0000000..f3810c3
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module1.yang
@@ -0,0 +1,32 @@
+module module1 {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/module1";
+
+ prefix m1;
+
+ import module3 {
+ prefix m3;
+ }
+
+ notification not1 {
+ uses m3:group {
+ augment "m1:cont2/m1:cont3/m1:cont4/cont5/cont6" {
+ list listl1 {
+ key "l2";
+ leaf l2 {
+ type string;
+ }
+ }
+ }
+ }
+
+ leaf-list ref {
+ type enumeration {
+ enum ten;
+ enum thousand;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module2.yang b/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module2.yang
new file mode 100644
index 0000000..3433fbe
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module2.yang
@@ -0,0 +1,39 @@
+module module2 {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/module2";
+
+ prefix m2;
+
+ grouping group2 {
+ container cont3 {
+ list listl2 {
+ key "key";
+
+ leaf key {
+ type string;
+ }
+ }
+ }
+
+ choice interface {
+ case physical {
+ container phy {
+ }
+ }
+
+ case virtual {
+ container vir {
+ }
+ }
+ }
+ }
+
+ grouping group3 {
+ container cont6 {
+ container cont7 {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module3.yang b/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module3.yang
new file mode 100644
index 0000000..5377e1a
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/interfileusesaug/module3.yang
@@ -0,0 +1,57 @@
+module module3 {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/module3";
+
+ prefix m3;
+
+ import module2 {
+ prefix m2;
+ }
+
+ grouping group {
+ leaf l1 {
+ type int8;
+ }
+
+ container cont2 {
+ leaf-list ll1 {
+ type decimal64 {
+ fraction-digits 1;
+ }
+ }
+ uses m2:group2 {
+ augment "cont3" {
+ container cont4 {
+ container cont5 {
+ uses m2:group3 {
+ augment "cont6" {
+ leaf ll5 {
+ type uint64;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ augment "interface" {
+ case vlan {
+ container vl {
+ }
+ }
+ }
+
+ augment "interface/physical" {
+ list interfaces {
+ key "int-name";
+ leaf int-name {
+ type string;
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/multiusesaug/multiusesaug.yang b/compiler/plugin/maven/src/test/resources/usesaugment/multiusesaug/multiusesaug.yang
new file mode 100644
index 0000000..55fc091
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/multiusesaug/multiusesaug.yang
@@ -0,0 +1,71 @@
+module multiusesaug {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/multiusesaug";
+
+ prefix mug;
+
+ container cont1 {
+ uses group {
+ augment "cont2/cont3/cont4/cont5/cont6" {
+ list listl1 {
+ key "l2";
+ leaf l2 {
+ type boolean;
+ }
+ }
+ }
+ }
+ }
+
+ grouping group {
+ leaf l1 {
+ type int8;
+ }
+
+ container cont2 {
+ leaf-list ll1 {
+ type decimal64 {
+ fraction-digits 1;
+ }
+ }
+ uses group2 {
+ augment "cont3" {
+ container cont4 {
+ container cont5 {
+ uses group3 {
+ augment "cont6" {
+ leaf ll5 {
+ type uint64;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ grouping group2 {
+ container cont3 {
+ list listl2 {
+ key "key";
+
+ leaf key {
+ type leafref {
+ path "../../../ll1";
+ }
+ }
+ }
+ }
+ }
+
+ grouping group3 {
+ container cont6 {
+ container cont7 {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/simpleusesaug/simpleusesaug.yang b/compiler/plugin/maven/src/test/resources/usesaugment/simpleusesaug/simpleusesaug.yang
new file mode 100644
index 0000000..c9287b9
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/simpleusesaug/simpleusesaug.yang
@@ -0,0 +1,35 @@
+module simpleusesaug {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/simpleusesaug";
+
+ prefix ua;
+
+ container cont1 {
+ uses group {
+ augment "cont2" {
+ list listl1 {
+ key "l2";
+ leaf l2 {
+ type boolean;
+ }
+ }
+ }
+ }
+ }
+
+ grouping group {
+ leaf l1 {
+ type int8;
+ }
+
+ container cont2 {
+ leaf-list ll1 {
+ type decimal64 {
+ fraction-digits 1;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/typedef/ietf-inet-types@2013-07-15.yang b/compiler/plugin/maven/src/test/resources/usesaugment/typedef/ietf-inet-types@2013-07-15.yang
new file mode 100644
index 0000000..c785cb0
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/typedef/ietf-inet-types@2013-07-15.yang
@@ -0,0 +1,81 @@
+module ietf-inet-types {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+
+ prefix "inet";
+
+ revision 2010-09-24 {
+ description "Initial revision.";
+ }
+
+ typedef port-number {
+ type uint16 {
+ range "0..65535";
+ }
+ }
+
+ typedef ip-address {
+ type union {
+ type inet:ipv4-address;
+ type inet:ipv6-address;
+ }
+ }
+
+ typedef ipv4-address {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '(%[\p{N}\p{L}]+)?';
+ }
+ }
+
+ typedef ipv6-address {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(%[\p{N}\p{L}]+)?';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(%.+)?';
+ }
+ }
+
+ typedef ip-address-no-zone {
+ type union {
+ type inet:ipv4-address-no-zone;
+ type inet:ipv6-address-no-zone;
+ }
+ }
+
+ typedef ipv4-address-no-zone {
+ type inet:ipv4-address {
+ pattern '[0-9\.]*';
+ }
+ }
+
+ typedef ipv6-address-no-zone {
+ type inet:ipv6-address {
+ pattern '[0-9a-fA-F:\.]*';
+ }
+ }
+
+ typedef domain-name {
+ type string {
+ pattern
+ '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+ + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+ + '|\.';
+ length "1..253";
+ }
+ }
+
+ typedef host {
+ type union {
+ type inet:ip-address;
+ type inet:domain-name;
+ }
+ }
+}
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/typedef/ietf-yang-types.yang b/compiler/plugin/maven/src/test/resources/usesaugment/typedef/ietf-yang-types.yang
new file mode 100644
index 0000000..8220767
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/typedef/ietf-yang-types.yang
@@ -0,0 +1,23 @@
+module ietf-yang-types {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/yang-types";
+
+ prefix type;
+
+ typedef date-and-time {
+ type string {
+ pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+ + '(Z|[\+\-]\d{2}:\d{2})';
+ }
+ }
+
+ typedef counter64 {
+ type uint64;
+ }
+
+ typedef timeticks {
+ type uint32;
+ }
+}
\ No newline at end of file
diff --git a/compiler/plugin/maven/src/test/resources/usesaugment/typedef/subscription.yang b/compiler/plugin/maven/src/test/resources/usesaugment/typedef/subscription.yang
new file mode 100644
index 0000000..2df42a7
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/usesaugment/typedef/subscription.yang
@@ -0,0 +1,321 @@
+module subscription {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/subscription";
+
+ prefix sub;
+
+ import ietf-yang-types {
+ prefix yang;
+ }
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ rpc establish-subscription {
+ input {
+ uses subscription-policy;
+ }
+ output {
+ uses subscription-response-with-hints {
+ augment "result" {
+ case success {
+ leaf identifier {
+ type subscription-id;
+ }
+ }
+ }
+
+ augment "result/no-success" {
+ leaf replay-start-time-hint {
+ type yang:date-and-time;
+ }
+ }
+ }
+ }
+ }
+
+ container subscriptions {
+ config false;
+ list subscription {
+ key "identifier";
+ config false;
+
+ leaf identifier {
+ type subscription-id;
+ }
+ leaf configured-subscription {
+ if-feature "configured-subscriptions";
+ type empty;
+ }
+
+ uses subscription-policy;
+ uses notification-origin-info {
+ if-feature "configured-subscriptions";
+ }
+
+ uses receiver-info {
+ refine receivers/receiver {
+ min-elements "1";
+ }
+ augment receivers/receiver {
+ leaf pushed-notifications {
+ type yang:counter64;
+ }
+ leaf excluded-notifications {
+ type yang:counter64;
+ }
+ leaf status {
+ type subscription-status-type;
+ mandatory true;
+ }
+ }
+ }
+ }
+ }
+
+ grouping subscription-policy {
+ uses subscription-policy-non-modifiable {
+ augment target/event-stream {
+ leaf replay-start-time {
+ if-feature "replay";
+ type yang:date-and-time;
+ }
+ }
+ }
+ }
+
+ grouping subscription-policy-non-modifiable {
+ leaf encoding {
+ type encoding;
+ }
+
+ choice target {
+ mandatory true;
+ case event-stream {
+ leaf stream {
+ type stream-type;
+ mandatory true;
+ }
+ }
+ }
+ }
+
+ grouping subscription-response-with-hints {
+ leaf subscription-result {
+ type subscription-result-type;
+ mandatory true;
+ }
+ choice result {
+ case no-success {
+ uses error-hints;
+ }
+ }
+ }
+
+ grouping error-hints {
+ leaf filter-failure {
+ type string;
+ }
+ }
+
+ grouping receiver-info {
+ container receivers {
+ list receiver {
+ key "address port";
+ min-elements 1;
+ leaf address {
+ type inet:host;
+ mandatory true;
+ }
+ leaf port {
+ type inet:port-number;
+ mandatory true;
+ }
+ leaf protocol {
+ type transport-protocol;
+ default "netconf-notif";
+ }
+ }
+ }
+ }
+
+ grouping notification-origin-info {
+ choice notification-origin {
+ case interface-originated {
+ leaf source-interface {
+ type string;
+ }
+ }
+ case address-originated {
+ leaf source-vrf {
+ type string;
+ }
+ leaf source-address {
+ type inet:ip-address-no-zone;
+ mandatory true;
+ }
+ }
+ }
+ }
+
+ grouping update-policy-modifiable {
+ choice update-trigger {
+ case periodic {
+ leaf period {
+ type yang:timeticks;
+ mandatory true;
+ }
+ leaf anchor-time {
+ type yang:date-and-time;
+ }
+ }
+ case on-change {
+ if-feature "on-change";
+ leaf dampening-period {
+ type yang:timeticks;
+ mandatory true;
+ }
+ }
+ }
+ }
+
+ grouping update-policy {
+ uses update-policy-modifiable {
+ augment "update-trigger/on-change" {
+ leaf no-synch-on-start {
+ type empty;
+ }
+ leaf-list excluded-change {
+ type change-type;
+ }
+ }
+ }
+ }
+
+ typedef transport-protocol {
+ type identityref {
+ base transport;
+ }
+ }
+
+ typedef encoding {
+ type identityref {
+ base encodings;
+ }
+ }
+
+ typedef stream-type {
+ type identityref {
+ base stream;
+ }
+ }
+
+ typedef subscription-result-type {
+ type identityref {
+ base subscription-result;
+ }
+ }
+
+ typedef subscription-id {
+ type uint32;
+ }
+
+ typedef subscription-status-type {
+ type identityref {
+ base subscription-status;
+ }
+ }
+
+ typedef change-type {
+ type enumeration {
+ enum "create";
+ enum "delete";
+ enum "insert";
+ enum "merge";
+ enum "move";
+ enum "replace";
+ enum "remove";
+ }
+ }
+
+ identity encodings {
+ }
+
+ identity encode-xml {
+ base encodings;
+ }
+
+ identity encode-json {
+ base encodings;
+ }
+
+ identity stream {
+ }
+
+ identity NETCONF {
+ base stream;
+ }
+
+ identity SYSLOG {
+ base stream;
+ }
+
+ identity subscription-result {
+ }
+
+ identity ok {
+ base subscription-result;
+ }
+
+ identity error {
+ base subscription-result;
+ }
+
+ identity transport {
+ }
+
+ identity netconf-notif {
+ base transport;
+ }
+
+ identity http2 {
+ base transport;
+ }
+
+ identity subscription-status {
+ }
+
+ identity active {
+ base subscription-status;
+ }
+
+ identity inactive {
+ base subscription-status;
+ }
+
+ identity suspended {
+ base subscription-status;
+ }
+
+ identity in-error {
+ base subscription-status;
+ }
+
+ feature replay {
+ description "This feature indicates that historical event display is
+ supported.";
+ }
+
+ feature configured-subscriptions {
+ description "This feature indicates that management plane configuration
+ of subscription is supported.";
+ }
+
+ feature on-change {
+ description "This feature indicates that on-change updates are
+ supported.";
+ }
+}
\ No newline at end of file
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DataTreeBuilderHelper.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DataTreeBuilderHelper.java
index 9120171..18c7e86 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DataTreeBuilderHelper.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DataTreeBuilderHelper.java
@@ -646,6 +646,7 @@
* Gets the registered module class. Loads the class and gets the
* augment class.
*/
+ curNode = getRootNode(curNode);
Class moduleClass = getClassLoaderForAugment(curNode, reg);
if (moduleClass == null) {
return null;
@@ -663,6 +664,19 @@
}
/**
+ * Returns the root node from the current node.
+ *
+ * @param curNode current YANG node
+ * @return root node
+ */
+ private YangNode getRootNode(YangNode curNode) {
+ while (curNode.getParent() != null) {
+ curNode = curNode.getParent();
+ }
+ return curNode;
+ }
+
+ /**
* Returns the data tree info from the parent node, so that its own bounded
* object can be taken out.
*
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java
index 79fe6ff..4b5906f 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java
@@ -216,7 +216,7 @@
*/
static Class<?> getClassLoaderForAugment(
YangNode curNode, DefaultYangModelRegistry registry) {
- return registry.getRegisteredClass(curNode.getParent());
+ return registry.getRegisteredClass(curNode);
}
/**
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java
index 8f3dc4a..9be6820 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java
@@ -375,13 +375,15 @@
YangSchemaNodeContextInfo context,
DefaultYangModelRegistry
reg) {
- YangSchemaNode augmentSchemaNode = context.getContextSwitchedNode();
- if (augmentSchemaNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
- YangSchemaNode moduleNode = ((YangNode) augmentSchemaNode).getParent();
-
- Class<?> moduleClass = reg.getRegisteredClass(moduleNode);
+ YangSchemaNode augment = context.getContextSwitchedNode();
+ if (augment.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
+ YangSchemaNode parent = ((YangNode) augment).getParent();
+ while (((YangNode) parent).getParent() != null) {
+ parent = ((YangNode) parent).getParent();
+ }
+ Class<?> moduleClass = reg.getRegisteredClass(parent);
if (moduleClass == null) {
- throw new ModelConvertorException(E_FAIL_TO_LOAD_CLASS + moduleNode
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_CLASS + parent
.getJavaClassNameOrBuiltInType());
}
return moduleClass.getClassLoader();
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
index 32bca18..6afb987 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
@@ -27,22 +27,42 @@
import org.onosproject.yang.gen.v1.yrtietftetopology.rev20160317.yrtietftetopology.telinkaugment.te.Config;
import org.onosproject.yang.gen.v1.yrtietftetopology.rev20160317.yrtietftetopology.telinkconfig.bundlestacklevel.Bundle;
import org.onosproject.yang.gen.v1.yrtietftetopology.rev20160317.yrtietftetopology.telinkconfig.bundlestacklevel.bundle.bundledlinks.BundledLink;
+import org.onosproject.yang.gen.v1.yrtietfyangtypes.rev20130715.yrtietfyangtypes.DateAndTime;
import org.onosproject.yang.gen.v1.yrtnetworktopology.rev20151208.yrtnetworktopology.TpId;
import org.onosproject.yang.gen.v1.yrtnetworktopology.rev20151208.yrtnetworktopology.networks.network.DefaultAugmentedNdNetwork;
import org.onosproject.yang.gen.v1.yrtnetworktopology.rev20151208.yrtnetworktopology.networks.network.augmentedndnetwork.Link;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.DefaultSubscriptions;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.DefaultTest;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.StreamType;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.check.Value;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.DefaultEstablishSubscriptionInput;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.DefaultEstablishSubscriptionOutput;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.establishsubscriptionoutput.result.augmentedresult.Success;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.receiverinfo.receivers.Receiver;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptionpolicy.target.eventstream.AugmentedEventStream;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptionpolicynonmodifiable.target.EventStream;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptions.Subscription;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptions.subscription.receivers.receiver.AugmentedReceiver;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.test.value.AugmentedValue;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultResourceData;
+import org.onosproject.yang.model.InnerModelObject;
import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectData;
import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.onosproject.yang.runtime.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.SerializerHelper.addToResourceId;
import static org.onosproject.yang.runtime.SerializerHelper.exitDataNode;
import static org.onosproject.yang.runtime.SerializerHelper.initializeDataNode;
+import static org.onosproject.yang.runtime.SerializerHelper.initializeResourceId;
/**
* Tests the YANG object building for the YANG data nodes based on the non
@@ -55,9 +75,11 @@
private static final String NW_TOPO_NAME_SPACE = "urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology";
private static final String TE_TOPO_NAME_SPACE =
"urn:ietf:params:xml:ns:yang:yrt-ietf-te-topology";
+ private static final String SUB_NAME_SPACE = "http://org/ns/yrt/subscription";
TestYangSerializerContext context = new TestYangSerializerContext();
DataNode.Builder dBlr;
String value;
+ private ResourceId.Builder rIdBlr;
public DataNode buildDataNodeForAugmentedLeaves() {
dBlr = initializeDataNode(context);
@@ -225,4 +247,187 @@
assertThat(id.uri().string(), is("101"));
assertThat(bundledLink.sequence(), is(100L));
}
+
+ /**
+ * Processes rpc input with uses augment.
+ */
+ @Test
+ public void processRpcInputForUsesAug() {
+ ResourceData data = buildDnForInputUsesAug();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultEstablishSubscriptionInput input =
+ ((DefaultEstablishSubscriptionInput) modelObject);
+ EventStream tgt = (EventStream) input.target();
+ StreamType stream = tgt.stream();
+ assertThat(stream.toString(), is("stream"));
+ Map<Class<? extends InnerModelObject>, InnerModelObject> augments =
+ tgt.augmentations();
+ Iterator<Map.Entry<Class<? extends InnerModelObject>,
+ InnerModelObject>> it = augments.entrySet().iterator();
+ InnerModelObject obj = it.next().getValue();
+ AugmentedEventStream es = (AugmentedEventStream) obj;
+ DateAndTime replay = es.replayStartTime();
+ assertThat(replay.toString(), is("2000-06-12T06:23:21"));
+ }
+
+ private ResourceData buildDnForInputUsesAug() {
+ value = null;
+ rIdBlr = initializeResourceId(context);
+ rIdBlr = addToResourceId(rIdBlr, "establish-subscription",
+ SUB_NAME_SPACE, value);
+ dBlr = initializeDataNode(rIdBlr);
+ dBlr = addDataNode(dBlr, "input", SUB_NAME_SPACE, value, null);
+ value = "stream";
+ dBlr = addDataNode(dBlr, "stream", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "2000-06-12T06:23:21";
+ dBlr = addDataNode(dBlr, "replay-start-time", SUB_NAME_SPACE,
+ value, null);
+ dBlr = exitDataNode(dBlr);
+ return DefaultResourceData.builder()
+ .addDataNode(dBlr.build()).resourceId(rIdBlr.build()).build();
+ }
+
+ /**
+ * Processes rpc output with uses augment.
+ */
+ @Test
+ public void processRpcOutputForUsesAug() {
+ ResourceData data = buildDnForOutputUsesAug();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultEstablishSubscriptionOutput output =
+ ((DefaultEstablishSubscriptionOutput) modelObject);
+ Success success = (Success) output.result();
+ assertThat(success.identifier().toString(), is("1123"));
+ }
+
+ private ResourceData buildDnForOutputUsesAug() {
+ value = null;
+ rIdBlr = initializeResourceId(context);
+ rIdBlr = addToResourceId(rIdBlr, "establish-subscription",
+ SUB_NAME_SPACE, value);
+ dBlr = initializeDataNode(rIdBlr);
+ dBlr = addDataNode(dBlr, "output", SUB_NAME_SPACE, value, null);
+ value = "1123";
+ dBlr = addDataNode(dBlr, "identifier", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ return DefaultResourceData.builder()
+ .addDataNode(dBlr.build()).resourceId(rIdBlr.build()).build();
+ }
+
+ /**
+ * Processes container with uses augment with leaf node.
+ */
+ @Test
+ public void processContainerForUsesAug() {
+ ResourceData data = buildDnForContainerUsesAug();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultSubscriptions deSub = (DefaultSubscriptions) modelObject;
+ List<Subscription> subList = deSub.subscription();
+ Subscription sub = subList.get(0);
+ assertThat(sub.identifier().toString(), is("1123"));
+ Receiver rec = sub.receivers().receiver().get(0);
+ assertThat(rec.address().toString(), is("dom1"));
+ assertThat(rec.port().toString(), is("111"));
+ Map<Class<? extends InnerModelObject>, InnerModelObject> augments =
+ rec.augmentations();
+ Iterator<Map.Entry<Class<? extends InnerModelObject>,
+ InnerModelObject>> it = augments.entrySet().iterator();
+ InnerModelObject obj = it.next().getValue();
+ AugmentedReceiver aug = (AugmentedReceiver) obj;
+ assertThat(aug.pushedNotifications().toString(), is("1113"));
+ assertThat(aug.excludedNotifications().toString(), is("456"));
+ assertThat(aug.status().toString(), is("subscription-status"));
+ }
+
+ private ResourceData buildDnForContainerUsesAug() {
+ value = null;
+ dBlr = initializeDataNode(context);
+ dBlr = addDataNode(dBlr, "subscriptions", SUB_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "subscription", SUB_NAME_SPACE, value, null);
+ value = "1123";
+ dBlr = addDataNode(dBlr, "identifier", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "receivers", SUB_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "receiver", SUB_NAME_SPACE, value, null);
+ value = "dom1";
+ dBlr = addDataNode(dBlr, "address", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "111";
+ dBlr = addDataNode(dBlr, "port", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "1113";
+ dBlr = addDataNode(dBlr, "pushed-notifications", SUB_NAME_SPACE, value,
+ null);
+ dBlr = exitDataNode(dBlr);
+ value = "456";
+ dBlr = addDataNode(dBlr, "excluded-notifications", SUB_NAME_SPACE,
+ value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "subscription-status";
+ dBlr = addDataNode(dBlr, "status", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ return DefaultResourceData.builder().addDataNode(dBlr.build()).build();
+ }
+
+ /**
+ * Processes container with uses augment with node.
+ */
+ @Test
+ public void processContainerTestForUsesAug() {
+ ResourceData data = buildDnForContainerTestUsesAug();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultTest test = (DefaultTest) modelObject;
+ Value val = test.value();
+ assertThat(val.stop().isPresent(), is(true));
+ Map<Class<? extends InnerModelObject>, InnerModelObject> augments =
+ val.augmentations();
+ Iterator<Map.Entry<Class<? extends InnerModelObject>,
+ InnerModelObject>> it = augments.entrySet().iterator();
+ InnerModelObject obj = it.next().getValue();
+ AugmentedValue pro = (AugmentedValue) obj;
+ assertThat(pro.proceed().isPresent(), is(true));
+ }
+
+ private ResourceData buildDnForContainerTestUsesAug() {
+ value = null;
+ dBlr = initializeDataNode(context);
+ dBlr = addDataNode(dBlr, "test", SUB_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "value", SUB_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "proceed", SUB_NAME_SPACE, value, null);
+ value = "true";
+ dBlr = addDataNode(dBlr, "isPresent", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "stop", SUB_NAME_SPACE, value, null);
+ value = "true";
+ dBlr = addDataNode(dBlr, "isPresent", SUB_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ return DefaultResourceData.builder().addDataNode(dBlr.build()).build();
+ }
}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
index 993db88..c2ca334 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
@@ -32,11 +32,46 @@
import org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.type.DefaultCon1;
import org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.type.Leaf1Union;
import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.val.AugmentedSchVal;
+import org.onosproject.yang.gen.v1.yrtietfinettypes.rev20130715.yrtietfinettypes.DomainName;
+import org.onosproject.yang.gen.v1.yrtietfinettypes.rev20130715.yrtietfinettypes.Host;
+import org.onosproject.yang.gen.v1.yrtietfinettypes.rev20130715.yrtietfinettypes.PortNumber;
+import org.onosproject.yang.gen.v1.yrtietfinettypes.rev20130715.yrtietfinettypes.host.HostUnion;
+import org.onosproject.yang.gen.v1.yrtietfyangtypes.rev20130715.yrtietfyangtypes.Counter64;
+import org.onosproject.yang.gen.v1.yrtietfyangtypes.rev20130715.yrtietfyangtypes.DateAndTime;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.Active;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.DefaultSubscriptions;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.Netconf;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.StreamType;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.SubscriptionId;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.SubscriptionStatusType;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.Subscriptions;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.DefaultEstablishSubscriptionInput;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.DefaultEstablishSubscriptionOutput;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.EstablishSubscriptionInput;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.EstablishSubscriptionOutput;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.establishsubscriptionoutput.result.augmentedresult.DefaultSuccess;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.establishsubscription.establishsubscriptionoutput.result.augmentedresult.Success;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.receiverinfo.DefaultReceivers;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.receiverinfo.Receivers;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.receiverinfo.receivers.DefaultReceiver;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.receiverinfo.receivers.Receiver;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptionpolicy.target.eventstream.AugmentedEventStream;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptionpolicy.target.eventstream.DefaultAugmentedEventStream;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptionpolicynonmodifiable.target.DefaultEventStream;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptionpolicynonmodifiable.target.EventStream;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptions.DefaultSubscription;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptions.Subscription;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptions.subscription.receivers.receiver.AugmentedReceiver;
+import org.onosproject.yang.gen.v1.yrtsubscription.yrtsubscription.subscriptions.subscription.receivers.receiver.DefaultAugmentedReceiver;
+import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultModelObjectData.Builder;
+import org.onosproject.yang.model.InnerModelObject;
+import org.onosproject.yang.model.InnerNode;
import org.onosproject.yang.model.KeyLeaf;
import org.onosproject.yang.model.LeafIdentifier;
import org.onosproject.yang.model.LeafListKey;
import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectId;
import org.onosproject.yang.model.NodeKey;
import org.onosproject.yang.model.ResourceData;
@@ -46,7 +81,9 @@
import java.math.BigInteger;
import java.util.Base64;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
@@ -63,16 +100,19 @@
import static org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.Ll6Enum.ENUM1;
import static org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.type.Con1.LeafIdentifier.LL;
import static org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.type.Leaf6Enum.ENUM2;
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
import static org.onosproject.yang.model.ModelObjectId.builder;
import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.processSchemaRegistry;
import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.registry;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
/**
* Unit test cases for resource id conversion from model object id.
*/
public class YtbResourceIdTest {
-
@Rule
public ExpectedException thrown = ExpectedException.none();
private ResourceData rscData;
@@ -285,4 +325,162 @@
assertThat(nameSpace, is(sid.namespace()));
assertThat(value, is(keyLeaf.leafValue()));
}
+
+ /**
+ * Processes rpc input with uses augment.
+ */
+ @Test
+ public void processRpcInputForUsesAug() {
+ setUp();
+ EstablishSubscriptionInput input = new
+ DefaultEstablishSubscriptionInput();
+ EventStream tgt = new DefaultEventStream();
+ tgt.stream(new StreamType(Netconf.class));
+ AugmentedEventStream es = new DefaultAugmentedEventStream();
+ es.replayStartTime(DateAndTime.fromString("2000-06-12T06:23:21"));
+ tgt.addAugmentation((InnerModelObject) es);
+ input.target(tgt);
+ data = new Builder();
+ data.addModelObject((ModelObject) input);
+ rscData = treeBuilder.getResourceData(data.build());
+
+ List<DataNode> inDn = rscData.dataNodes();
+ String ns = "http://org/ns/yrt/subscription";
+ Iterator<DataNode> it = inDn.iterator();
+
+ DataNode in = it.next();
+ validateDataNode(in, "input", ns, SINGLE_INSTANCE_NODE, true, null);
+
+ Map<NodeKey, DataNode> child = ((InnerNode) in).childNodes();
+ List<DataNode> inputDN = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ inputDN.add(c.getValue());
+ }
+
+ Iterator<DataNode> it1 = inputDN.iterator();
+ validateDataNode(it1.next(), "stream", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "stream");
+ validateDataNode(it1.next(), "replay-start-time", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true,
+ "2000-06-12T06:23:21");
+ }
+
+ /**
+ * Processes rpc output with uses augment.
+ */
+ @Test
+ public void processRpcOutputForUsesAug() {
+ setUp();
+ EstablishSubscriptionOutput output = new
+ DefaultEstablishSubscriptionOutput();
+ Success result = new DefaultSuccess();
+ result.identifier(new SubscriptionId(876L));
+ output.result(result);
+ data = new Builder();
+ data.addModelObject((ModelObject) output);
+ rscData = treeBuilder.getResourceData(data.build());
+
+ List<DataNode> inDn = rscData.dataNodes();
+ String ns = "http://org/ns/yrt/subscription";
+ Iterator<DataNode> it = inDn.iterator();
+
+ DataNode in = it.next();
+ validateDataNode(in, "output", ns, SINGLE_INSTANCE_NODE, true, null);
+
+ Map<NodeKey, DataNode> child = ((InnerNode) in).childNodes();
+ List<DataNode> inputDN = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ inputDN.add(c.getValue());
+ }
+
+ Iterator<DataNode> it1 = inputDN.iterator();
+ validateDataNode(it1.next(), "identifier", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "876");
+ }
+
+ /**
+ * Processes container with uses augment.
+ */
+ @Test
+ public void processContainerForUsesAug() {
+ setUp();
+ Subscriptions subs = new DefaultSubscriptions();
+ Subscription sub = new DefaultSubscription();
+ sub.identifier(new SubscriptionId(1112L));
+ AugmentedReceiver aug = new DefaultAugmentedReceiver();
+ aug.pushedNotifications(new Counter64(new BigInteger("1113")));
+ aug.excludedNotifications(new Counter64(new BigInteger("456")));
+ aug.status(new SubscriptionStatusType(Active.class));
+ Receivers rcs = new DefaultReceivers();
+ Receiver rc = new DefaultReceiver();
+ rc.address(new Host(new HostUnion(new DomainName("dom1"))));
+ rc.port(new PortNumber(111));
+ rc.addAugmentation((InnerModelObject) aug);
+ rcs.addToReceiver(rc);
+ sub.receivers(rcs);
+ subs.addToSubscription(sub);
+ data = new Builder();
+ data.addModelObject((ModelObject) subs);
+ rscData = treeBuilder.getResourceData(data.build());
+
+ List<DataNode> subsDn = rscData.dataNodes();
+ String ns = "http://org/ns/yrt/subscription";
+ Iterator<DataNode> it = subsDn.iterator();
+
+ DataNode subsNode = it.next();
+ validateDataNode(subsNode, "subscriptions", ns, SINGLE_INSTANCE_NODE,
+ true, null);
+
+ Map<NodeKey, DataNode> child = ((InnerNode) subsNode).childNodes();
+ List<DataNode> list = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ list.add(c.getValue());
+ }
+
+ it = list.iterator();
+ DataNode subscription = it.next();
+ validateDataNode(subscription, "subscription", ns, MULTI_INSTANCE_NODE,
+ true, null);
+
+ child = ((InnerNode) subscription).childNodes();
+ list = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ list.add(c.getValue());
+ }
+
+ it = list.iterator();
+ validateDataNode(it.next(), "identifier", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "1112");
+ DataNode receivers = it.next();
+ validateDataNode(receivers, "receivers", ns, SINGLE_INSTANCE_NODE,
+ true, null);
+
+ child = ((InnerNode) receivers).childNodes();
+ list = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ list.add(c.getValue());
+ }
+ it = list.iterator();
+ DataNode receiver = it.next();
+ validateDataNode(receiver, "receiver", ns, MULTI_INSTANCE_NODE, true,
+ null);
+
+ child = ((InnerNode) receiver).childNodes();
+ list = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ list.add(c.getValue());
+ }
+ it = list.iterator();
+ validateDataNode(it.next(), "address", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "dom1");
+ validateDataNode(it.next(), "port", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "111");
+ validateDataNode(it.next(), "pushed-notifications", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "1113");
+ validateDataNode(it.next(), "excluded-notifications", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "456");
+ validateDataNode(it.next(), "status", ns,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true,
+ "subscription-status");
+ }
}
diff --git a/runtime/src/test/resources/schemaProviderTestYangFiles/yrt-subscription.yang b/runtime/src/test/resources/schemaProviderTestYangFiles/yrt-subscription.yang
new file mode 100644
index 0000000..152c674
--- /dev/null
+++ b/runtime/src/test/resources/schemaProviderTestYangFiles/yrt-subscription.yang
@@ -0,0 +1,343 @@
+module yrt-subscription {
+ yang-version 1;
+
+ namespace
+ "http://org/ns/yrt/subscription";
+
+ prefix sub;
+
+ import yrt-ietf-yang-types {
+ prefix yang;
+ }
+
+ import yrt-ietf-inet-types {
+ prefix inet;
+ }
+
+ rpc establish-subscription {
+ input {
+ uses subscription-policy;
+ }
+ output {
+ uses subscription-response-with-hints {
+ augment "result" {
+ case success {
+ leaf identifier {
+ type subscription-id;
+ }
+ }
+ }
+
+ augment "result/no-success" {
+ leaf replay-start-time-hint {
+ type yang:date-and-time;
+ }
+ }
+ }
+ }
+ }
+
+ container subscriptions {
+ config false;
+ list subscription {
+ key "identifier";
+ config false;
+
+ leaf identifier {
+ type subscription-id;
+ }
+ leaf configured-subscription {
+ if-feature "configured-subscriptions";
+ type empty;
+ }
+
+ uses subscription-policy;
+ uses notification-origin-info {
+ if-feature "configured-subscriptions";
+ }
+
+ uses receiver-info {
+ refine receivers/receiver {
+ min-elements "1";
+ }
+ augment receivers/receiver {
+ leaf pushed-notifications {
+ type yang:counter64;
+ }
+ leaf excluded-notifications {
+ type yang:counter64;
+ }
+ leaf status {
+ type subscription-status-type;
+ mandatory true;
+ }
+ }
+ }
+ }
+ }
+
+ container test {
+ uses check {
+ augment "value/" {
+ container proceed {
+ leaf isPresent {
+ type boolean;
+ }
+ }
+ }
+ }
+ }
+
+ grouping check {
+ container value {
+ container stop {
+ leaf isPresent {
+ type boolean;
+ }
+ }
+ }
+ }
+
+ grouping subscription-policy {
+ uses subscription-policy-non-modifiable {
+ augment target/event-stream {
+ leaf replay-start-time {
+ if-feature "replay";
+ type yang:date-and-time;
+ }
+ }
+ }
+ }
+
+ grouping subscription-policy-non-modifiable {
+ leaf encoding {
+ type encoding;
+ }
+
+ choice target {
+ mandatory true;
+ case event-stream {
+ leaf stream {
+ type stream-type;
+ mandatory true;
+ }
+ }
+ }
+ }
+
+ grouping subscription-response-with-hints {
+ leaf subscription-result {
+ type subscription-result-type;
+ mandatory true;
+ }
+ choice result {
+ case no-success {
+ uses error-hints;
+ }
+ }
+ }
+
+ grouping error-hints {
+ leaf filter-failure {
+ type string;
+ }
+ }
+
+ grouping receiver-info {
+ container receivers {
+ list receiver {
+ key "address port";
+ min-elements 1;
+ leaf address {
+ type inet:host;
+ mandatory true;
+ }
+ leaf port {
+ type inet:port-number;
+ mandatory true;
+ }
+ leaf protocol {
+ type transport-protocol;
+ default "netconf-notif";
+ }
+ }
+ }
+ }
+
+ grouping notification-origin-info {
+ choice notification-origin {
+ case interface-originated {
+ leaf source-interface {
+ type string;
+ }
+ }
+ case address-originated {
+ leaf source-vrf {
+ type string;
+ }
+ leaf source-address {
+ type inet:ip-address-no-zone;
+ mandatory true;
+ }
+ }
+ }
+ }
+
+ grouping update-policy-modifiable {
+ choice update-trigger {
+ case periodic {
+ leaf period {
+ type yang:timeticks;
+ mandatory true;
+ }
+ leaf anchor-time {
+ type yang:date-and-time;
+ }
+ }
+ case on-change {
+ if-feature "on-change";
+ leaf dampening-period {
+ type yang:timeticks;
+ mandatory true;
+ }
+ }
+ }
+ }
+
+ grouping update-policy {
+ uses update-policy-modifiable {
+ augment "update-trigger/on-change" {
+ leaf no-synch-on-start {
+ type empty;
+ }
+ leaf-list excluded-change {
+ type change-type;
+ }
+ }
+ }
+ }
+
+ typedef transport-protocol {
+ type identityref {
+ base transport;
+ }
+ }
+
+ typedef encoding {
+ type identityref {
+ base encodings;
+ }
+ }
+
+ typedef stream-type {
+ type identityref {
+ base stream;
+ }
+ }
+
+ typedef subscription-result-type {
+ type identityref {
+ base subscription-result;
+ }
+ }
+
+ typedef subscription-id {
+ type uint32;
+ }
+
+ typedef subscription-status-type {
+ type identityref {
+ base subscription-status;
+ }
+ }
+
+ typedef change-type {
+ type enumeration {
+ enum "create";
+ enum "delete";
+ enum "insert";
+ enum "merge";
+ enum "move";
+ enum "replace";
+ enum "remove";
+ }
+ }
+
+ identity encodings {
+ }
+
+ identity encode-xml {
+ base encodings;
+ }
+
+ identity encode-json {
+ base encodings;
+ }
+
+ identity stream {
+ }
+
+ identity NETCONF {
+ base stream;
+ }
+
+ identity SYSLOG {
+ base stream;
+ }
+
+ identity subscription-result {
+ }
+
+ identity ok {
+ base subscription-result;
+ }
+
+ identity error {
+ base subscription-result;
+ }
+
+ identity transport {
+ }
+
+ identity netconf-notif {
+ base transport;
+ }
+
+ identity http2 {
+ base transport;
+ }
+
+ identity subscription-status {
+ }
+
+ identity active {
+ base subscription-status;
+ }
+
+ identity inactive {
+ base subscription-status;
+ }
+
+ identity suspended {
+ base subscription-status;
+ }
+
+ identity in-error {
+ base subscription-status;
+ }
+
+ feature replay {
+ description "This feature indicates that historical event display is
+ supported.";
+ }
+
+ feature configured-subscriptions {
+ description "This feature indicates that management plane configuration
+ of subscription is supported.";
+ }
+
+ feature on-change {
+ description "This feature indicates that on-change updates are
+ supported.";
+ }
+}
\ No newline at end of file