janani b
Committed by Patrick Liu

[ONOS-4842] Leafref implementation for augment and uses

Change-Id: I919553a64d683aff65a8f16e2de783702dd5a45f
Showing 89 changed files with 1675 additions and 481 deletions
......@@ -22,8 +22,10 @@ import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
/**
* Abstraction of YANG resolvable information. Abstracted to obtain the
* information required for linking resolution.
*
* @param <T> YANG resolvable info
*/
public interface Resolvable {
public interface Resolvable<T> {
/**
* Returns the status of resolution. If completely resolved returns enum
......@@ -48,8 +50,9 @@ public interface Resolvable {
/**
* Resolves the linking.
*
* @return list of entities to be added for resolution
* @throws DataModelException data model exception
*/
void resolve()
T resolve()
throws DataModelException;
}
......
......@@ -442,8 +442,9 @@ public class YangAugment
}
@Override
public void resolve() throws DataModelException {
public Object resolve() throws DataModelException {
// Resolving of target node is being done in XPathLinker.
return null;
}
/**
......
......@@ -109,6 +109,7 @@ import java.io.Serializable;
}
@Override
public void resolve() throws DataModelException {
public Object resolve() throws DataModelException {
return null;
}
}
......
......@@ -18,6 +18,7 @@ package org.onosproject.yangutils.datamodel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
......
......@@ -13,34 +13,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.linker.impl;
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
import org.onosproject.yangutils.datamodel.YangIfFeature;
import org.onosproject.yangutils.datamodel.YangBase;
import org.onosproject.yangutils.datamodel.YangIdentityRef;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
/**
* Represents implementation of information about entity being resolved.
*
* @param <T> type of entity being resolved, uses / grouping
*/
public class YangEntityToResolveInfoImpl<T> implements YangEntityToResolveInfo<T>, Serializable {
public class YangEntityToResolveInfoImpl<T> implements YangEntityToResolveInfo<T>, Serializable, LocationInfo {
private static final long serialVersionUID = 806201659L;
// Parsable node for which resolution is to be performed.
/**
* Parsable node for which resolution is to be performed.
*/
private T entityToResolve;
// Holder of the YANG construct for which resolution has to be carried out.
/**
* Holder of the YANG construct for which resolution has to be carried out.
*/
private YangNode holderOfEntityToResolve;
/**
* Error line number.
*/
private transient int lineNumber;
/**
* Error character position in number.
*/
private transient int charPositionInLine;
@Override
public T getEntityToResolve() {
return entityToResolve;
......@@ -61,33 +66,23 @@ public class YangEntityToResolveInfoImpl<T> implements YangEntityToResolveInfo<T
this.holderOfEntityToResolve = holderOfEntityToResolve;
}
/**
* Retrieves the prefix of the entity.
*
* @return entities prefix
* @throws LinkerException linker error
*/
public String getEntityPrefix()
throws LinkerException {
if (getEntityToResolve() == null) {
return null;
}
@Override
public int getLineNumber() {
return lineNumber;
}
String prefix;
T entityToBeResolved = getEntityToResolve();
if (entityToBeResolved instanceof YangType) {
prefix = ((YangType<?>) entityToBeResolved).getPrefix();
} else if (entityToBeResolved instanceof YangUses) {
prefix = ((YangUses) entityToBeResolved).getPrefix();
} else if (entityToBeResolved instanceof YangIfFeature) {
prefix = ((YangIfFeature) entityToBeResolved).getPrefix();
} else if (entityToBeResolved instanceof YangBase) {
prefix = ((YangBase) entityToBeResolved).getBaseIdentifier().getPrefix();
} else if (entityToBeResolved instanceof YangIdentityRef) {
prefix = ((YangIdentityRef) entityToBeResolved).getBaseIdentity().getPrefix();
} else {
throw new LinkerException("Linker Exception: Entity to resolved is other than type/uses");
}
return prefix;
@Override
public int getCharPosition() {
return charPositionInLine;
}
@Override
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
@Override
public void setCharPosition(int charPositionInLine) {
this.charPositionInLine = charPositionInLine;
}
}
......
......@@ -80,7 +80,7 @@ public class YangIdentityRef extends YangNode implements Parsable, Resolvable, S
}
@Override
public void resolve() throws DataModelException {
public Object resolve() throws DataModelException {
// Check if the derived info is present.
YangIdentity identity = getReferredIdentity();
......@@ -92,10 +92,11 @@ public class YangIdentityRef extends YangNode implements Parsable, Resolvable, S
while (identity.getBaseNode() != null) {
if (identity.getBaseNode().getResolvableStatus() != ResolvableStatus.RESOLVED) {
setResolvableStatus(ResolvableStatus.INTRA_FILE_RESOLVED);
return;
return null;
}
identity = identity.getBaseNode().getReferredIdentity();
}
return null;
}
/**
......
......@@ -170,7 +170,7 @@ public class YangIfFeature implements Parsable, Resolvable, Serializable {
}
@Override
public void resolve() throws DataModelException {
public Object resolve() throws DataModelException {
YangFeature feature = getReferredFeature();
// check whether feature has if-feature
......@@ -181,9 +181,10 @@ public class YangIfFeature implements Parsable, Resolvable, Serializable {
YangIfFeature ifFeature = ifFeatureIterator.next();
if (ifFeature.getResolvableStatus() != ResolvableStatus.RESOLVED) {
setResolvableStatus(ResolvableStatus.INTRA_FILE_RESOLVED);
return;
return null;
}
}
}
return null;
}
}
......
......@@ -16,17 +16,18 @@
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.YangErrMsgConstants.DATA_MISSING_ERROR_TAG;
......@@ -47,7 +48,7 @@ import static org.onosproject.yangutils.datamodel.utils.YangErrMsgConstants.INST
* @param <T> YANG leafref info
*/
public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangIfFeatureHolder,
YangXPathResolver, YangAppErrorHolder {
YangXPathResolver, YangAppErrorHolder, LocationInfo {
private static final long serialVersionUID = 286201644L;
......@@ -100,6 +101,61 @@ public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangI
private List<YangIfFeature> ifFeatureList;
/**
* Parent node of the leafref's leaf.
*/
private YangNode parentNodeOfLeafref;
/**
* Error line number.
*/
private transient int lineNumber;
/**
* Error character position in number.
*/
private transient int charPositionInLine;
/**
* Prefix in the nodes of the leafref path and its imported node name.
*/
private Map<String, String> prefixAndItsImportedModule;
/**
* Returns the prefix in the leafref path and its imported node name.
*
* @return the list of leafref prefix and imported node name
*/
public Map<String, String> getPrefixAndItsImportedModule() {
return prefixAndItsImportedModule;
}
/**
* Sets the prefix in the leafref path and its imported node name.
*
* @param prefixAndItsImportedModule the list of leafref prefix and imported node name
*/
public void setPrefixAndItsImportedModule(Map<String, String> prefixAndItsImportedModule) {
this.prefixAndItsImportedModule = prefixAndItsImportedModule;
}
/**
* Returns the parent node from the leafref's leaf.
*
* @return parent node of the leafref
*/
public YangNode getParentNodeOfLeafref() {
return parentNodeOfLeafref;
}
/**
* Sets the parent node from the leafref's leaf.
*
* @param parentNodeOfLeafref parent node of the leafref
*/
public void setParentNodeOfLeafref(YangNode parentNodeOfLeafref) {
this.parentNodeOfLeafref = parentNodeOfLeafref;
}
/**
* YANG application error information.
*/
private YangAppErrorInfo yangAppErrorInfo;
......@@ -294,7 +350,7 @@ public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangI
}
@Override
public void resolve() throws DataModelException {
public Object resolve() throws DataModelException {
if (getReferredLeafOrLeafList() == null) {
throw new DataModelException("Linker Error: The leafref does not refer to any leaf/leaf-list.");
......@@ -306,6 +362,7 @@ public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangI
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
return null;
}
/**
......@@ -443,4 +500,24 @@ public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangI
throw new DataModelException("Linker Error: The leafref must refer only to leaf/leaf-list.");
}
}
@Override
public int getLineNumber() {
return lineNumber;
}
@Override
public int getCharPosition() {
return charPositionInLine;
}
@Override
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
@Override
public void setCharPosition(int charPositionInLine) {
this.charPositionInLine = charPositionInLine;
}
}
......
......@@ -16,15 +16,15 @@
package org.onosproject.yangutils.datamodel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
/*
......@@ -119,6 +119,26 @@ public class YangList
private List<String> keyList;
/**
* Reference RFC 6020.
*
* The "unique" statement is used to put constraints on valid list
* entries. It takes as an argument a string that contains a space-
* separated list of schema node identifiers, which MUST be given in the
* descendant form. Each such schema node identifier MUST refer to a leaf.
*
* If one of the referenced leafs represents configuration data, then
* all of the referenced leafs MUST represent configuration data.
*
* The "unique" constraint specifies that the combined values of all the
* leaf instances specified in the argument string, including leafs with
* default values, MUST be unique within all list entry instances in
* which all referenced leafs exist.
*
* List of unique leaf/leaf-list names
*/
private List<String> uniqueList;
/**
* List of leaves.
*/
private List<YangLeaf> listOfLeaf;
......@@ -271,6 +291,24 @@ public class YangList
}
/**
* Returns the list of unique field names.
*
* @return the list of unique field names
*/
public List<String> getUniqueList() {
return uniqueList;
}
/**
* Sets the list of unique field names.
*
* @param uniqueList the list of unique field names
*/
private void setUniqueList(List<String> uniqueList) {
this.uniqueList = uniqueList;
}
/**
* Returns the list of key field names.
*
* @return the list of key field names
......@@ -309,6 +347,24 @@ public class YangList
}
/**
* Adds a unique field name.
*
* @param unique unique field name.
* @throws DataModelException a violation of data model rules
*/
public void addUnique(String unique)
throws DataModelException {
if (getUniqueList() == null) {
setUniqueList(new LinkedList<>());
}
if (getUniqueList().contains(unique)) {
throw new DataModelException("A leaf identifier must not appear more than once in the\n" +
" unique");
}
getUniqueList().add(unique);
}
/**
* Returns the list of leaves.
*
* @return the list of leaves
......@@ -489,11 +545,11 @@ public class YangList
validateConfig(leaves, leafLists);
/* A list must have atleast one key leaf if config is true */
if (isConfig && (keys == null || leaves == null && leafLists == null) && !isUsesPresentInList()
if (isConfig && (keys == null || leaves == null) && !isUsesPresentInList()
&& !isListPresentInGrouping()) {
throw new DataModelException("A list must have atleast one key leaf if config is true;");
} else if (keys != null) {
validateKey(leaves, leafLists, keys);
validateKey(leaves, keys);
}
}
......@@ -501,7 +557,7 @@ public class YangList
* Sets the config's value to all leaf if leaf's config statement is not
* specified.
*
* @param leaves list of leaf attributes of YANG list
* @param leaves list of leaf attributes of YANG list
* @param leafLists list of leaf-list attributes of YANG list
*/
private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) {
......@@ -534,7 +590,7 @@ public class YangList
/**
* Validates config statement of YANG list.
*
* @param leaves list of leaf attributes of YANG list
* @param leaves list of leaf attributes of YANG list
* @param leafLists list of leaf-list attributes of YANG list
* @throws DataModelException a violation of data model rules
*/
......@@ -567,16 +623,15 @@ public class YangList
/**
* Validates key statement of list.
*
* @param leaves list of leaf attributes of list
* @param leaves list of leaf attributes of list
* @param leafLists list of leaf-list attributes of list
* @param keys list of key attributes of list
* @param keys list of key attributes of list
* @throws DataModelException a violation of data model rules
*/
private void validateKey(List<YangLeaf> leaves, List<YangLeafList> leafLists, List<String> keys)
private void validateKey(List<YangLeaf> leaves, List<String> keys)
throws DataModelException {
boolean leafFound = false;
List<YangLeaf> keyLeaves = new LinkedList<>();
List<YangLeafList> keyLeafLists = new LinkedList<>();
/*
* 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
......@@ -597,20 +652,6 @@ public class YangList
}
}
if (leafLists != null && !leafLists.isEmpty()) {
for (YangLeafList leafList : leafLists) {
if (key.equals(leafList.getName())) {
if (leafList.getDataType().getDataType() == YangDataTypes.EMPTY) {
throw new DataModelException(" A leaf-list that is part of the key" +
" must not be the built-in type \"empty\".");
}
leafFound = true;
keyLeafLists.add(leafList);
break;
}
}
}
if (!leafFound && !isUsesPresentInList() && !isListPresentInGrouping()) {
throw new DataModelException("An identifier, in key, must refer to a child leaf of the list");
}
......@@ -627,17 +668,6 @@ public class YangList
" \"config\" as the list itself.");
}
}
/*
* All key leafs in a list MUST have the same value for their "config"
* as the list itself.
*/
for (YangLeafList keyLeafList : keyLeafLists) {
if (isConfig() != keyLeafList.isConfig()) {
throw new DataModelException("All key leaf-lists in a list must have the same value for their" +
" \"config\" as the list itself.");
}
}
}
@Override
......
......@@ -272,12 +272,12 @@ public abstract class YangNode
* @throws CloneNotSupportedException clone is not supported by the referred
* node
*/
public YangNode clone()
public YangNode clone(YangUses yangUses)
throws CloneNotSupportedException {
YangNode clonedNode = (YangNode) super.clone();
if (clonedNode instanceof YangLeavesHolder) {
try {
cloneLeaves((YangLeavesHolder) clonedNode);
cloneLeaves((YangLeavesHolder) clonedNode, yangUses);
} catch (DataModelException e) {
throw new CloneNotSupportedException(e.getMessage());
}
......@@ -299,7 +299,7 @@ public abstract class YangNode
* @param dstRootNode destination node where the sub tree needs to be cloned
* @throws DataModelException data model error
*/
public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode)
public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode, YangUses yangUses)
throws DataModelException {
YangNode nextNodeToClone = srcRootNode;
......@@ -327,7 +327,7 @@ public abstract class YangNode
throw new DataModelException("Internal error: Cloning failed, source tree null pointer reached");
}
if (curTraversal != PARENT) {
newNode = nextNodeToClone.clone();
newNode = nextNodeToClone.clone(yangUses);
detectCollisionWhileCloning(clonedTreeCurNode, newNode, curTraversal);
}
......
......@@ -239,7 +239,7 @@ public class YangType<T>
}
@Override
public void resolve()
public Object resolve()
throws DataModelException {
/*
* Check whether the data type is derived.
......@@ -260,6 +260,7 @@ public class YangType<T>
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
return null;
}
/**
......
......@@ -26,6 +26,8 @@ import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.getParentNodeInGenCode;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLeafrefUnderGroupingForLeaf;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLeafrefUnderGroupingForLeafList;
/*-
* Reference RFC 6020.
......@@ -126,6 +128,16 @@ public class YangUses
private List<List<YangLeafList>> resolvedGroupingLeafLists;
/**
* Effective list of leaf lists of grouping that needs to replicated at YANG uses.
*/
private List<YangEntityToResolveInfoImpl> entityToResolveInfoList;
/**
* Current grouping depth for uses.
*/
private int currentGroupingDepth;
/**
* Creates an YANG uses node.
*/
public YangUses() {
......@@ -138,6 +150,38 @@ public class YangUses
}
/**
* Returns the list of entity to resolve.
*
* @return the list of entity to resolve
*/
public List<YangEntityToResolveInfoImpl> getEntityToResolveInfoList() {
return entityToResolveInfoList;
}
/**
* Sets the list of entity to resolve.
*
* @param entityToResolveInfoList the list of entity to resolve
*/
public void setEntityToResolveInfoList(List<YangEntityToResolveInfoImpl> entityToResolveInfoList) {
this.entityToResolveInfoList = entityToResolveInfoList;
}
/**
* Adds an entity to resolve in list.
*
* @param entityToResolve entity to resolved
* @throws DataModelException a violation of data model rules
*/
public void addEntityToResolve(YangEntityToResolveInfoImpl entityToResolve)
throws DataModelException {
if (getEntityToResolveInfoList() == null) {
setEntityToResolveInfoList(new LinkedList<YangEntityToResolveInfoImpl>());
}
getEntityToResolveInfoList().add(entityToResolve);
}
/**
* Returns the referred group.
*
* @return the referred group
......@@ -314,7 +358,7 @@ public class YangUses
}
@Override
public void resolve()
public Object resolve()
throws DataModelException {
YangGrouping referredGrouping = getRefGroup();
......@@ -337,7 +381,13 @@ public class YangUses
((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leaf.getName(),
YangConstructType.LEAF_DATA);
clonedLeaf = leaf.clone();
if (getCurrentGroupingDepth() == 0) {
YangEntityToResolveInfoImpl resolveInfo = resolveLeafrefUnderGroupingForLeaf(clonedLeaf,
usesParentLeavesHolder, this);
if (resolveInfo != null) {
addEntityToResolve(resolveInfo);
}
}
} catch (CloneNotSupportedException | DataModelException e) {
throw new DataModelException(e.getMessage());
}
......@@ -353,7 +403,13 @@ public class YangUses
((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leafList.getName(),
YangConstructType.LEAF_LIST_DATA);
clonedLeafList = leafList.clone();
if (getCurrentGroupingDepth() == 0) {
YangEntityToResolveInfoImpl resolveInfo =
resolveLeafrefUnderGroupingForLeafList(clonedLeafList, usesParentLeavesHolder);
if (resolveInfo != null) {
addEntityToResolve(resolveInfo);
}
}
} catch (CloneNotSupportedException | DataModelException e) {
throw new DataModelException(e.getMessage());
}
......@@ -364,11 +420,12 @@ public class YangUses
}
try {
YangNode.cloneSubTree(referredGrouping, usesParentNode);
YangNode.cloneSubTree(referredGrouping, usesParentNode, this);
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
updateClonedLeavesUnionEnumRef(usesParentLeavesHolder);
return getEntityToResolveInfoList();
}
/**
......@@ -378,7 +435,7 @@ public class YangUses
* @param usesHolder holder of uses
*/
private void addResolvedUsesInfoOfGrouping(YangUses usesInGrouping,
YangLeavesHolder usesHolder) throws DataModelException {
YangLeavesHolder usesHolder) throws DataModelException {
for (YangNode usesResolvedNode : usesInGrouping.getUsesResolvedNodeList()) {
addNodeOfGrouping(usesResolvedNode);
}
......@@ -402,7 +459,7 @@ public class YangUses
* @throws DataModelException a violation in data model rule
*/
private List<YangLeaf> cloneLeavesList(List<YangLeaf> listOfLeaves,
YangLeavesHolder usesParentNode) throws DataModelException {
YangLeavesHolder usesParentNode) throws DataModelException {
if (listOfLeaves == null || listOfLeaves.size() == 0) {
throw new DataModelException("No leaves to clone");
}
......@@ -433,7 +490,7 @@ public class YangUses
* @return cloned list of leaf list
*/
private List<YangLeafList> cloneListOfLeafList(List<YangLeafList> listOfLeafList,
YangLeavesHolder usesParentNode) throws DataModelException {
YangLeavesHolder usesParentNode) throws DataModelException {
if (listOfLeafList == null || listOfLeafList.size() == 0) {
throw new DataModelException("No leaf lists to clone");
}
......@@ -556,4 +613,13 @@ public class YangUses
public void setIfFeatureList(List<YangIfFeature> ifFeatureList) {
this.ifFeatureList = ifFeatureList;
}
public void setCurrentGroupingDepth(int currentGroupingDepth) {
this.currentGroupingDepth = currentGroupingDepth;
}
public int getCurrentGroupingDepth() {
return currentGroupingDepth;
}
}
......
......@@ -177,11 +177,11 @@ public class YangLinkerManager
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_DERIVED_DATA_TYPE);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_LEAFREF);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_BASE);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_IDENTITYREF);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_LEAFREF);
} catch (DataModelException e) {
String errorInfo = "Error in file: " + yangNode.getName() + " at line: "
+ e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE + e.getMessage();
......
......@@ -16,18 +16,28 @@
package org.onosproject.yangutils.linker.impl;
import java.util.List;
import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangAugmentableNode;
import org.onosproject.yangutils.datamodel.YangAugmentedInfo;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import static org.onosproject.yangutils.utils.UtilConstants.COLON;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
/**
* Represent utilities for YANG linker.
*/
......@@ -36,6 +46,10 @@ public final class YangLinkerUtils {
private YangLinkerUtils() {
}
private static final int IDENTIFIER_LENGTH = 64;
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
private static final String XML = "xml";
/**
* Detects collision between target nodes leaf/leaf-list or child node with augmented leaf/leaf-list or child node.
*
......@@ -119,4 +133,99 @@ public final class YangLinkerUtils {
detectCollision((YangAugment) info, augment);
}
}
/**
* Returns list of path names that are needed from augment.
*
* @param augment instance of YANG augment
* @param remainingAncestors ancestor count to move in augment path
* @return list of path names needed in leafref
*/
public static List<String> getPathWithAugment(YangAugment augment, int remainingAncestors) {
String augmentName = augment.getName();
List<String> listOfPathName = new ArrayList<>();
if (augmentName.contains(SLASH_FOR_STRING)) {
String[] augmentNodeNames = augmentName.split(SLASH_FOR_STRING);
for (String valueInAugment : augmentNodeNames) {
if (valueInAugment != null && valueInAugment != EMPTY_STRING && !valueInAugment.isEmpty()) {
listOfPathName.add(valueInAugment);
}
}
}
for (int countOfAncestor = 0; countOfAncestor < remainingAncestors; countOfAncestor++) {
listOfPathName.remove(listOfPathName.size() - 1);
}
return listOfPathName;
}
/**
* Skips the invalid nodes which cannot have data from YANG.
*
* @param currentParent current parent node reference
* @param leafref instance of YANG leafref
* @return parent node which can hold data
* @throws LinkerException a violation of linker rules
*/
public static YangNode skipInvalidDataNodes(YangNode currentParent, YangLeafRef leafref) throws LinkerException {
while (currentParent instanceof YangChoice || currentParent instanceof YangCase) {
if (currentParent.getParent() == null) {
throw new LinkerException("YANG file error: The target node, in the leafref path " +
leafref.getPath() + ", is invalid.");
}
currentParent = currentParent.getParent();
}
return currentParent;
}
/**
* Checks and return valid node identifier.
*
* @param nodeIdentifierString string from yang file
* @param yangConstruct yang construct for creating error message
* @return valid node identifier
*/
public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
YangConstructType yangConstruct) {
String[] tmpData = nodeIdentifierString.split(Pattern.quote(COLON));
if (tmpData.length == 1) {
YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct));
return nodeIdentifier;
} else if (tmpData.length == 2) {
YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct));
nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct));
return nodeIdentifier;
} else {
throw new LinkerException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
" is not valid.");
}
}
/**
* Validates identifier and returns concatenated string if string contains plus symbol.
*
* @param identifier string from yang file
* @param yangConstruct yang construct for creating error message=
* @return concatenated string after removing double quotes
*/
public static String getValidIdentifier(String identifier, YangConstructType yangConstruct) {
if (identifier.length() > IDENTIFIER_LENGTH) {
throw new LinkerException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is " +
"greater than 64 characters.");
} else if (!IDENTIFIER_PATTERN.matcher(identifier).matches()) {
throw new LinkerException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is not " +
"valid.");
} else if (identifier.toLowerCase().startsWith(XML)) {
throw new LinkerException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifier +
" must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
} else {
return identifier;
}
}
}
......
......@@ -16,31 +16,41 @@
package org.onosproject.yangutils.linker.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.onosproject.yangutils.datamodel.YangAtomicPath;
import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangImport;
import org.onosproject.yangutils.datamodel.YangInclude;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTER_TO_INTER;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTER_TO_INTRA;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTRA_TO_INTER;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTER;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTRA;
import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
/**
* Represents x-path linking.
......@@ -194,31 +204,35 @@ public class YangXpathLinker<T> {
/**
* Process absolute node path for target leaf.
*
* @param absPaths absolute path node list
* @param root root node
* @param atomicPaths atomic path node list
* @param root root node
* @param leafref instance of YANG leafref
* @return linked target node
*/
T processLeafRefXpathLinking(List<YangAtomicPath> absPaths, YangNode root) {
public T processLeafRefXpathLinking(List<YangAtomicPath> atomicPaths, YangNode root, YangLeafRef leafref) {
YangNode targetNode = null;
setRootNode(root);
setPrefixResolverTypes(new HashMap<>());
parsePrefixResolverList(absPaths);
YangAtomicPath leafRefPath = absPaths.get(absPaths.size() - 1);
parsePrefixResolverList(atomicPaths);
YangAtomicPath leafRefPath = atomicPaths.get(atomicPaths.size() - 1);
// When leaf-ref path contains only one absolute path.
if (absPaths.size() == 1) {
targetNode = getTargetNodewhenSizeIsOne(absPaths);
if (atomicPaths.size() == 1) {
targetNode = getTargetNodewhenSizeIsOne(atomicPaths);
} else {
absPaths.remove(absPaths.size() - 1);
atomicPaths.remove(atomicPaths.size() - 1);
setAbsPaths(absPaths);
setAbsPaths(atomicPaths);
targetNode = parseData(root);
}
if (targetNode == null) {
targetNode = searchInSubModule(root);
}
// Invalid path presence in the node list is checked.
validateInvalidNodesInThePath(leafref);
if (targetNode != null) {
YangLeaf targetLeaf = searchReferredLeaf(targetNode, leafRefPath.getNodeIdentifier().getName());
if (targetLeaf == null) {
......@@ -227,9 +241,12 @@ public class YangXpathLinker<T> {
if (targetLeafList != null) {
return (T) targetLeafList;
} else {
throw new LinkerException(
"YANG file error: Unable to find base leaf/leaf-list for given leafref "
+ leafRefPath.getNodeIdentifier().getName());
LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
"leaf/leaf-list for given leafref path "
+ leafref.getPath());
linkerException.setCharPosition(leafref.getCharPosition());
linkerException.setLine(leafref.getLineNumber());
throw linkerException;
}
}
return (T) targetLeaf;
......@@ -238,6 +255,30 @@ public class YangXpathLinker<T> {
}
/**
* Validates the nodes in the path for any invalid node.
*
* @param leafref instance of YANG leafref
*/
private void validateInvalidNodesInThePath(YangLeafRef leafref) {
Map<YangAtomicPath, YangNode> nodes = getResolvedNodes();
Iterator<Map.Entry<YangAtomicPath, YangNode>> nodesIterator = nodes.entrySet().iterator();
while (nodesIterator.hasNext()) {
Map.Entry<YangAtomicPath, YangNode> nodeInList = nodesIterator.next();
YangNode nodeInPath = nodeInList.getValue();
if (nodeInPath instanceof YangGrouping || nodeInPath instanceof YangUses
|| nodeInPath instanceof YangTypeDef || nodeInPath instanceof YangCase
|| nodeInPath instanceof YangChoice) {
LinkerException linkerException = new LinkerException("YANG file error: The target node, in the " +
"leafref path " + leafref.getPath() + ", is invalid.");
linkerException.setCharPosition(leafref.getCharPosition());
linkerException.setLine(leafref.getLineNumber());
throw linkerException;
}
}
}
/**
* Returns target node when leaf-ref has only one absolute path in list.
*
* @param absPaths absolute paths
......@@ -289,9 +330,13 @@ public class YangXpathLinker<T> {
}
YangLeavesHolder holder = (YangLeavesHolder) targetNode;
List<YangLeaf> leaves = holder.getListOfLeaf();
for (YangLeaf leaf : leaves) {
if (leaf.getName().equals(leafName)) {
return leaf;
if (leaves != null && !leaves.isEmpty()) {
Iterator<YangLeaf> leafIterator = leaves.listIterator();
while (leafIterator.hasNext()) {
YangLeaf leaf = leafIterator.next();
if (leaf.getName().equals(leafName)) {
return leaf;
}
}
}
return null;
......@@ -311,9 +356,13 @@ public class YangXpathLinker<T> {
}
YangLeavesHolder holder = (YangLeavesHolder) targetNode;
List<YangLeafList> leavesList = holder.getListOfLeafList();
for (YangLeafList leafList : leavesList) {
if (leafList.getName().equals(leafListName)) {
return leafList;
if (leavesList != null && !leavesList.isEmpty()) {
Iterator<YangLeafList> leafListIterator = leavesList.listIterator();
while (leafListIterator.hasNext()) {
YangLeafList leafList = leafListIterator.next();
if (leafList.getName().equals(leafListName)) {
return leafList;
}
}
}
return null;
......@@ -709,6 +758,15 @@ public class YangXpathLinker<T> {
}
while (node != null) {
if (node instanceof YangInput) {
if (curNodeId.getName().equalsIgnoreCase(INPUT)) {
return node;
}
} else if (node instanceof YangOutput) {
if (curNodeId.getName().equalsIgnoreCase(OUTPUT)) {
return node;
}
}
if (node.getName().equals(curNodeId.getName())) {
return node;
}
......
......@@ -16,8 +16,6 @@
package org.onosproject.yangutils.parser.impl;
import java.util.Stack;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
......@@ -42,12 +40,14 @@ import org.onosproject.yangutils.parser.impl.listeners.DefaultListener;
import org.onosproject.yangutils.parser.impl.listeners.DescriptionListener;
import org.onosproject.yangutils.parser.impl.listeners.EnumListener;
import org.onosproject.yangutils.parser.impl.listeners.EnumerationListener;
import org.onosproject.yangutils.parser.impl.listeners.ErrorAppTagListener;
import org.onosproject.yangutils.parser.impl.listeners.ErrorMessageListener;
import org.onosproject.yangutils.parser.impl.listeners.FeatureListener;
import org.onosproject.yangutils.parser.impl.listeners.FractionDigitsListener;
import org.onosproject.yangutils.parser.impl.listeners.GroupingListener;
import org.onosproject.yangutils.parser.impl.listeners.IdentityListener;
import org.onosproject.yangutils.parser.impl.listeners.IdentityrefListener;
import org.onosproject.yangutils.parser.impl.listeners.IfFeatureListener;
import org.onosproject.yangutils.parser.impl.listeners.IdentityListener;
import org.onosproject.yangutils.parser.impl.listeners.ImportListener;
import org.onosproject.yangutils.parser.impl.listeners.IncludeListener;
import org.onosproject.yangutils.parser.impl.listeners.InputListener;
......@@ -83,13 +83,15 @@ import org.onosproject.yangutils.parser.impl.listeners.SubModuleListener;
import org.onosproject.yangutils.parser.impl.listeners.TypeDefListener;
import org.onosproject.yangutils.parser.impl.listeners.TypeListener;
import org.onosproject.yangutils.parser.impl.listeners.UnionListener;
import org.onosproject.yangutils.parser.impl.listeners.UniqueListener;
import org.onosproject.yangutils.parser.impl.listeners.UnitsListener;
import org.onosproject.yangutils.parser.impl.listeners.UsesListener;
import org.onosproject.yangutils.parser.impl.listeners.ValueListener;
import org.onosproject.yangutils.parser.impl.listeners.VersionListener;
import org.onosproject.yangutils.parser.impl.listeners.WhenListener;
import org.onosproject.yangutils.parser.impl.listeners.ErrorMessageListener;
import org.onosproject.yangutils.parser.impl.listeners.ErrorAppTagListener;
import java.util.Stack;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.handleUnsupportedYangConstruct;
import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
import static org.onosproject.yangutils.utils.UtilConstants.UNSUPPORTED_YANG_CONSTRUCT;
......@@ -109,6 +111,34 @@ public class TreeWalkListener implements GeneratedYangListener {
private YangNode rootNode;
/**
* Parent depth of grouping count for any node.
*/
private int groupingDepth;
/**
* Returns number of grouping parents, by a node, at any level.
*
* @return depth of grouping
*/
public int getGroupingDepth() {
return groupingDepth;
}
/**
* Sets number of grouping parents by a node at any level.
*/
public void increaseGroupingDepth() {
groupingDepth++;
}
/**
* Sets number of grouping parents by a node at any level.
*/
public void decreaseGroupingDepth() {
groupingDepth--;
}
/**
* Returns stack of parsable data.
*
* @return stack of parsable data
......@@ -956,7 +986,7 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterUniqueStatement(GeneratedYangParser.UniqueStatementContext ctx) {
handleUnsupportedYangConstruct(YangConstructType.UNIQUE_DATA, ctx, CURRENTLY_UNSUPPORTED);
UniqueListener.processUniqueEntry(this, ctx);
}
@Override
......
......@@ -106,6 +106,8 @@ public final class GroupingListener {
// Validate sub statement cardinality.
validateSubStatementsCardinality(ctx);
// Increase the grouping count by one.
listener.increaseGroupingDepth();
Parsable curData = listener.getParsedDataStack().peek();
// Check for identifier collision
......@@ -149,6 +151,8 @@ public final class GroupingListener {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), EXIT);
// Decrease the grouping count by one.
listener.decreaseGroupingDepth();
if (listener.getParsedDataStack().peek() instanceof YangGrouping) {
listener.getParsedDataStack().pop();
} else {
......
......@@ -100,6 +100,8 @@ public final class LeafrefListener {
YangLeafRef<?> leafRef = new YangLeafRef<>();
leafRef.setLineNumber(errorLine);
leafRef.setCharPosition(errorPosition);
Parsable typeData = listener.getParsedDataStack().pop();
if (!(typeData instanceof YangType)) {
......@@ -130,11 +132,13 @@ public final class LeafrefListener {
}
leafRef.setResolvableStatus(UNRESOLVED);
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
(YangNode) parentNodeOfLeaf, errorLine, errorPosition);
addToResolutionList(resolutionInfo);
leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeaf);
if (listener.getGroupingDepth() == 0) {
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
(YangNode) parentNodeOfLeaf, errorLine, errorPosition);
addToResolutionList(resolutionInfo);
}
break;
case LEAF_LIST_DATA:
......@@ -151,14 +155,19 @@ public final class LeafrefListener {
}
leafRef.setResolvableStatus(UNRESOLVED);
leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafList);
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
(YangNode) parentNodeOfLeafList, errorLine, errorPosition);
addToResolutionList(resolutionInfoImpl);
if (listener.getGroupingDepth() == 0) {
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
(YangNode) parentNodeOfLeafList, errorLine, errorPosition);
addToResolutionList(resolutionInfoImpl);
}
break;
case TYPEDEF_DATA:
Parsable parentNodeOfLeafref = listener.getParsedDataStack().peek();
leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafref);
/*
* Do not add the leaf ref to resolution list. It needs to be
* added to resolution list, when leaf/leaf list references to
......
......@@ -54,6 +54,7 @@ import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorTyp
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.validateUniqueInList;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityNonZero;
......@@ -174,6 +175,7 @@ public final class ListListener {
YangList yangList = (YangList) listener.getParsedDataStack().peek();
try {
yangList.validateDataOnExit();
validateUniqueInList(yangList, ctx);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
LIST_DATA, ctx.identifier().getText(), EXIT, e.getMessage()));
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* 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.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.UNIQUE_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
.constructExtendedListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
* ABNF grammar as per RFC6020
* unique-stmt = unique-keyword sep unique-arg-str stmtend
*
* ANTLR grammar rule
* uniqueStatement: UNIQUE_KEYWORD unique STMTEND;
* unique : string;
*/
/**
* Represesnts listener based call back function corresponding to the "unique" rule
* defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class UniqueListener {
/**
* Creates a new unique listener.
*/
private UniqueListener() {
}
/**
* It is called when parser receives an input matching the grammar rule
* (unique), perform validations and updates the data model tree.
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processUniqueEntry(TreeWalkListener listener,
GeneratedYangParser.UniqueStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, UNIQUE_DATA, ctx.unique().getText(), ENTRY);
Parsable tmpData = listener.getParsedDataStack().peek();
if (listener.getParsedDataStack().peek() instanceof YangList) {
YangList yangList = (YangList) tmpData;
String tmpUniqueValue = removeQuotesAndHandleConcat(ctx.unique().getText());
if (tmpUniqueValue.contains(" ")) {
String[] uniqueValues = tmpUniqueValue.split(" ");
for (String uniqueValue : uniqueValues) {
try {
yangList.addUnique(uniqueValue);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
UNIQUE_DATA,
ctx.unique().getText(), ENTRY, e.getMessage()));
}
}
} else {
try {
yangList.addUnique(tmpUniqueValue);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, UNIQUE_DATA,
ctx.unique().getText(), ENTRY, e.getMessage()));
}
}
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, UNIQUE_DATA, ctx.unique().getText(),
ENTRY));
}
}
}
\ No newline at end of file
......@@ -137,6 +137,7 @@ public final class UsesListener {
YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), USES_DATA, ctx);
usesNode.setNodeIdentifier(nodeIdentifier);
usesNode.setCurrentGroupingDepth(listener.getGroupingDepth());
YangNode curNode = (YangNode) curData;
try {
......
......@@ -444,33 +444,6 @@ public class ConfigListenerTest {
* config statement's value.
*/
@Test
public void processNoConfigListSubStatementLeafList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/NoConfigListSubStatementLeafList.yang");
assertThat((node instanceof YangModule), is(true));
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// Check whether the config value is set correctly.
YangList list1 = (YangList) yangNode.getChild();
assertThat(list1.getName(), is("valid"));
assertThat(list1.isConfig(), is(true));
ListIterator<YangLeafList> leafListIterator = list1.getListOfLeafList().listIterator();
YangLeafList leafListInfo = leafListIterator.next();
// Check whether config value is set correctly.
assertThat(leafListInfo.getName(), is("invalid-interval"));
assertThat(leafListInfo.isConfig(), is(true));
}
/**
* Checks when config is not specified, the default is same as the parent's schema node's
* config statement's value.
*/
@Test
public void processNoConfigListSubStatementLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/NoConfigListSubStatementLeaf.yang");
......
......@@ -143,26 +143,6 @@ public class KeyListenerTest {
}
/**
* Checks key values are set correctly.
*/
@Test
public void processConfigFalseValidKeyValidLeafList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ConfigFalseValidKeyValidLeafList.yang");
assertThat((node instanceof YangModule), is(true));
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// Check whether the list is child of module
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
ListIterator<String> keyList = yangList.getKeyList().listIterator();
assertThat(keyList.next(), is("invalid-interval"));
}
/**
* Checks whether exception is thrown when list's config is set to true and there is no key.
*/
@Test
......@@ -233,26 +213,6 @@ public class KeyListenerTest {
}
/**
* Checks whether exception is thrown when key leaf-list identifier is not found in list.
*/
@Test
public void processInvalidLeafListIdentifier() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("An identifier, in key, must refer to a child leaf of the list");
YangNode node = manager.getDataModel("src/test/resources/InvalidLeafListIdentifier.yang");
}
/**
* Checks whether exception is thrown when key leaf-list is of type empty.
*/
@Test
public void processKeyLeafListTypeEmpty() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("A leaf-list that is part of the key must not be the built-in type \"empty\".");
YangNode node = manager.getDataModel("src/test/resources/KeyLeafListTypeEmpty.yang");
}
/**
* Checks whether exception is thrown when key leaf is of type empty.
*/
@Test
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* 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.yangutils.parser.impl.listeners;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import java.io.IOException;
import java.util.ListIterator;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
/**
* Test cases for unique listener.
*/
public class UniqueListenerTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks unique statement as sub-statement of list.
*/
@Test
public void processListSubStatementUnique() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ListSubStatementUnique.yang");
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// Check whether the list is child of module
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
assertThat(yangList.getUniqueList().listIterator().next(), is("invalid-interval"));
}
/**
* Check multiple unique values.
*/
@Test
public void processMultipleUniqueValues() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/MultipleUniqueValues.yang");
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// Check whether the list is child of module
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
ListIterator<String> listIterator;
String list;
listIterator = yangList.getUniqueList().listIterator();
list = listIterator.next();
assertThat(list, is("ospf"));
list = listIterator.next();
assertThat(list, is("isis"));
}
}
\ No newline at end of file
......@@ -16,17 +16,11 @@
package org.onosproject.yangutils.plugin.manager;
import java.io.IOException;
import java.util.List;
import java.util.ListIterator;
import org.junit.Test;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangFeature;
import org.onosproject.yangutils.datamodel.YangIfFeature;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
......@@ -35,6 +29,9 @@ import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import java.io.IOException;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
......@@ -221,111 +218,4 @@ public class IntraFileIfFeatureLinkingTest {
assertThat(ifFeature.getName().getName(), is("local-storage"));
assertThat(ifFeature.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
}
/**
* Checks addition of if-feature list to leafref.
*/
@Test
public void processSelfFileLinkingWithFeatureReferredByLeafref()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfFileLinkingWithFeatureReferredByLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("syslog"));
List<YangFeature> featureList = yangNode.getFeatureList();
YangFeature feature = featureList.iterator().next();
assertThat(feature.getName(), is("local-storage"));
YangContainer container = (YangContainer) yangNode.getChild();
assertThat(container.getName(), is("speed"));
List<YangLeaf> listOfLeaf = container.getListOfLeaf();
YangLeaf leaf = listOfLeaf.iterator().next();
assertThat(leaf.getName(), is("local-storage-limit"));
List<YangIfFeature> ifFeatureList = leaf.getIfFeatureList();
YangIfFeature ifFeature = ifFeatureList.iterator().next();
assertThat(ifFeature.getName().getName(), is("local-storage"));
assertThat(ifFeature.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
ListIterator<YangLeaf> listOfLeafInModule = yangNode.getListOfLeaf().listIterator();
YangLeaf yangLeaf = listOfLeafInModule.next();
assertThat(yangLeaf.getName(), is("storage-value"));
YangLeafRef leafRef = (YangLeafRef) yangLeaf.getDataType().getDataTypeExtendedInfo();
assertThat(leafRef.getEffectiveDataType().getDataType(), is(YangDataTypes.UINT64));
List<YangIfFeature> ifFeatureListInLeafref = leafRef.getIfFeatureList();
YangIfFeature ifFeatureInLeafref = ifFeatureListInLeafref.iterator().next();
assertThat(ifFeatureInLeafref.getName().getName(), is("local-storage"));
assertThat(ifFeatureInLeafref.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
}
/**
* Checks addition of if-feature list to leafref when referred leaf is again having leafref in it.
*/
@Test
public void processSelfFileLinkingWithFeatureReferredByMultiLeafref()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfFileLinkingWithFeatureReferredByMultiLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("syslog"));
List<YangFeature> featureList = yangNode.getFeatureList();
YangFeature feature = featureList.iterator().next();
assertThat(feature.getName(), is("local-storage"));
YangContainer container = (YangContainer) yangNode.getChild();
assertThat(container.getName(), is("speed"));
List<YangLeaf> listOfLeaf = container.getListOfLeaf();
YangLeaf leaf = listOfLeaf.iterator().next();
assertThat(leaf.getName(), is("local-storage-limit"));
List<YangIfFeature> ifFeatureList = leaf.getIfFeatureList();
YangIfFeature ifFeature = ifFeatureList.iterator().next();
assertThat(ifFeature.getName().getName(), is("local-storage"));
assertThat(ifFeature.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
ListIterator<YangLeaf> listOfLeafInModule = yangNode.getListOfLeaf().listIterator();
YangLeaf yangLeaf = listOfLeafInModule.next();
assertThat(yangLeaf.getName(), is("storage-value"));
YangLeafRef leafRef = (YangLeafRef) yangLeaf.getDataType().getDataTypeExtendedInfo();
assertThat(leafRef.getEffectiveDataType().getDataType(), is(YangDataTypes.UINT64));
List<YangIfFeature> ifFeatureListInLeafref = leafRef.getIfFeatureList();
YangIfFeature ifFeatureInLeafref = ifFeatureListInLeafref.iterator().next();
assertThat(ifFeatureInLeafref.getName().getName(), is("main-storage"));
assertThat(ifFeatureInLeafref.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
YangIfFeature ifFeatureInLeafref1 = ifFeatureListInLeafref.iterator().next();
assertThat(ifFeatureInLeafref1.getName().getName(), is("main-storage"));
assertThat(ifFeatureInLeafref1.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
}
}
......
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
leaf-list invalid {
type "string";
units "seconds";
status current;
reference "RFC 6020";
}
}
}
\ No newline at end of file
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
leaf-list invalid-interval {
type "empty";
units "seconds";
status current;
reference "RFC 6020";
}
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ module Test {
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
key "invalid";
leaf-list invalid-interval {
type "uint16";
units "seconds";
......@@ -13,5 +13,8 @@ module Test {
status current;
reference "RFC 6020";
}
leaf invalid {
type "uint16";
}
}
}
\ No newline at end of file
......
......@@ -3,12 +3,15 @@ module Test {
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
key "invalid";
max-elements 3;
leaf-list invalid-interval {
type "uint16";
units "seconds";
description "Interval before a route is declared invalid";
}
leaf invalid {
type "uint16";
}
}
}
\ No newline at end of file
......
......@@ -3,12 +3,15 @@ module Test {
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
key "invalid";
min-elements 3;
leaf-list invalid-interval {
type "uint16";
units "seconds";
description "Interval before a route is declared invalid";
}
leaf invalid {
type "uint16";
}
}
}
\ No newline at end of file
......
......@@ -3,12 +3,13 @@ module Test {
namespace http://huawei.com;
prefix Ant;
list valid {
unique "invalid-interval";
key "invalid-interval";
leaf-list invalid-interval {
leaf invalid-interval {
type "uint16";
units "seconds";
status current;
reference "RFC 6020";
}
}
}
\ No newline at end of file
}
......
......@@ -3,9 +3,16 @@ module Test {
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
leaf-list invalid-interval {
type "string";
key "ospf";
unique "ospf isis";
leaf ospf {
type "uint16";
units "seconds";
status current;
reference "RFC 6020";
}
leaf isis {
type "uint16";
units "seconds";
status current;
reference "RFC 6020";
......
......@@ -3,7 +3,7 @@ module Test {
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
key "invalid";
leaf-list invalid-interval {
type union {
type int32;
......@@ -12,5 +12,8 @@ module Test {
}
}
}
leaf invalid {
type string;
}
}
}
......
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "/define/network-id";
}
}
}
\ No newline at end of file
......@@ -103,7 +103,11 @@
description
"References a link in a specific network.";
leaf link-ref {
type link-id;
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/../"+
"network-ref]/lnk:link/lnk:link-id";
require-instance false;
}
description
"A type for an absolute reference a link instance.
(This type should not be used for relative references.
......@@ -116,7 +120,12 @@
description
"References a termination point in a specific node.";
leaf tp-ref {
type tp-id;
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/../"+
"network-ref]/nd:node[nd:node-id=current()/../"+
"node-ref]/lnk:termination-point/lnk:tp-id";
require-instance false;
}
description
"A type for an absolute reference to a termination point.
(This type should not be used for relative references.
......@@ -150,13 +159,18 @@
"This container holds the logical source of a particular
link.";
leaf source-node {
type nd:node-id;
type leafref {
path "../../../nd:node/nd:node-id";
}
mandatory true;
description
"Source node identifier, must be in same topology.";
}
leaf source-tp {
type tp-id;
type leafref {
path "../../../nd:node[nd:node-id=current()/../"+
"source-node]/termination-point/tp-id";
}
description
"Termination point within source node that terminates
the link.";
......@@ -167,14 +181,19 @@
"This container holds the logical destination of a
particular link.";
leaf dest-node {
type nd:node-id;
type leafref {
path "../../../nd:node/nd:node-id";
}
mandatory true;
description
"Destination node identifier, must be in the same
network.";
}
leaf dest-tp {
type tp-id;
type leafref {
path "../../../nd:node[nd:node-id=current()/../"+
"dest-node]/termination-point/tp-id";
}
description
"Termination point within destination node that
terminates the link.";
......@@ -192,13 +211,20 @@
"Identifies the link, or links, that this link
is dependent on.";
leaf network-ref {
type nd:network-id;
type leafref {
path "../../../nd:supporting-network/nd:network-ref";
require-instance false;
}
description
"This leaf identifies in which underlay topology
supporting link is present.";
}
leaf link-ref {
type link-id;
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/"+
"../network-ref]/link/link-id";
require-instance false;
}
description
"This leaf identifies a link which is a part
of this link's underlay. Reference loops, in which
......@@ -237,19 +263,30 @@
The corresponding information is simply provided by the
implementing system.";
leaf network-ref {
type nd:network-id;
type leafref {
path "../../../nd:supporting-node/nd:network-ref";
require-instance false;
}
description
"This leaf identifies in which topology the
supporting termination point is present.";
}
leaf node-ref {
type nd:node-id;
type leafref {
path "../../../nd:supporting-node/nd:node-ref";
require-instance false;
}
description
"This leaf identifies in which node the supporting
termination point is present.";
}
leaf tp-ref {
type tp-id;
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/"+
"../network-ref]/nd:node[nd:node-id=current()/../"+
"node-ref]/termination-point/tp-id";
require-instance false;
}
description
"Reference to the underlay node, must be in a
different topology";
......
......@@ -87,7 +87,10 @@
"Contains the information necessary to reference a network,
for example an underlay network.";
leaf network-ref {
type network-id;
type leafref {
path "/nd:networks/nd:network/nd:network-id";
require-instance false;
}
description
"Used to reference a network, for example an underlay
network.";
......@@ -98,7 +101,11 @@
description
"Contains the information necessary to reference a node.";
leaf node-ref {
type node-id;
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/../"+
"network-ref]/nd:node/nd:node-id";
require-instance false;
}
description
"Used to reference a node.
Nodes are identified relative to the network they are
......@@ -135,7 +142,10 @@
"An underlay network, used to represent layered network
topologies.";
leaf network-ref {
type network-id;
type leafref {
path "/networks/network/network-id";
require-instance false;
}
description
"References the underlay network.";
}
......@@ -157,13 +167,19 @@
this node is supported by. Used to represent layering
structure.";
leaf network-ref {
type network-id;
type leafref {
path "../../../supporting-network/network-ref";
require-instance false;
}
description
"References the underlay network that the
underlay node is part of.";
}
leaf node-ref {
type node-id;
type leafref {
path "/networks/network/node/node-id";
require-instance false;
}
description
"References the underlay node itself.";
}
......
......@@ -515,14 +515,14 @@
"A container controlling performance metric throttle.";
container performance-metric-throttle {
if-feature te-performance-metric;
/*must "suppression-interval >= measure-interval" {
must "suppression-interval >= measure-interval" {
error-message
"suppression-interval cannot be less then
measure-interval.";
description
"Constraint on suppression-interval and
measure-interval.";
}*/
}
description
"Link performance information in real time.";
reference
......@@ -549,7 +549,7 @@
}
leaf suppression-interval {
type uint32 {
range "1..max";
range "1 .. max";
}
default 120;
description
......@@ -633,13 +633,25 @@
"Identify the sequence in the bundle.";
}
leaf src-tp-ref {
type nt:tp-id;
type leafref {
path "../../../../../../nw:node[nw:node-id = "
+ "current()/../../../../../nt:source/"
+ "nt:source-node]/"
+ "nt:termination-point/nt:tp-id";
require-instance true;
}
description
"Reference to another TE termination point on the
same souruce node.";
}
leaf des-tp-ref {
type nt:tp-id;
type leafref {
path "../../../../../../nw:node[nw:node-id = "
+ "current()/../../../../../nt:destination/"
+ "nt:dest-node]/"
+ "nt:termination-point/nt:tp-id";
require-instance true;
}
description
"Reference to another TE termination point on the
same destination node.";
......@@ -682,7 +694,9 @@
leaf-list te-link-template {
if-feature template;
type te-template-name;
type leafref {
path "../../../../../te/templates/link-template/name";
}
description
"The reference to a TE link template.";
}
......@@ -862,12 +876,16 @@
RFC4203: OSPF Extensions in Support of Generalized
Multi-Protocol Label Switching (GMPLS).";
leaf switching-capability {
type string;
type identityref {
base te-types:switching-capabilities;
}
description
"Switching Capability for this interface.";
}
leaf encoding {
type string;
type identityref {
base te-types:lsp-encoding-types;
}
description
"Encoding supported by this interface.";
}
......@@ -929,12 +947,16 @@
"RFC6001: Generalized MPLS (GMPLS) Protocol Extensions
for Multi-Layer and Multi-Region Networks (MLN/MRN).";
leaf upper-sc {
type string;
type identityref {
base te-types:switching-capabilities;
}
description
"Switching Capability for this interface.";
}
leaf upper-encoding {
type string;
type identityref {
base te-types:lsp-encoding-types;
}
description
"Encoding supported by this interface.";
}
......@@ -1140,13 +1162,17 @@
uses te-node-tunnel-termination-capability;
leaf switching-capability {
type string;
type identityref {
base te-types:switching-capabilities;
}
mandatory true;
description
"Switching Capability.";
}
leaf encoding {
type string;
type identityref {
base te-types:lsp-encoding-types;
}
mandatory true;
description
"Encoding type.";
......@@ -1162,7 +1188,9 @@
leaf-list te-node-template {
if-feature template;
type te-template-name;
type leafref {
path "../../../../../te/templates/node-template/name";
}
description
"The reference to a TE node template.";
}
......@@ -1231,7 +1259,9 @@
}
container from {
leaf tp-ref {
type nt:tp-id;
type leafref {
path "../../../../../../nt:termination-point/nt:tp-id";
}
description
"Relative reference to source termination point.";
}
......@@ -1240,7 +1270,9 @@
}
container to {
leaf tp-ref {
type nt:tp-id;
type leafref {
path "../../../../../../nt:termination-point/nt:tp-id";
}
description
"Relative reference to destination termination point.";
}
......@@ -1402,7 +1434,9 @@
The capability information can be used to compute
the tunnel path.";
leaf link-tp {
type nt:tp-id;
type leafref {
path "../../../../../nt:termination-point/nt:tp-id";
}
description
"Link termination point.";
}
......@@ -1562,22 +1596,37 @@
description
"References a TE topology.";
leaf provider-id-ref {
type te-global-id;
type leafref {
path "/nw:networks/nw:network[nw:network-id = "
+ "current()/../network-id-ref]/tet:te/tet:provider-id";
require-instance false;
}
description
"A reference to a provider-id.";
}
leaf client-id-ref {
type te-global-id;
type leafref {
path "/nw:networks/nw:network[nw:network-id = "
+ "current()/../network-id-ref]/tet:te/tet:client-id";
require-instance false;
}
description
"A reference to a client-id.";
}
leaf te-topology-id-ref {
type tet:te-topology-id;
type leafref {
path "/nw:networks/nw:network[nw:network-id = "
+ "current()/../network-id-ref]/tet:te/tet:te-topology-id";
require-instance false;
}
description
"A reference to a te-topology-id.";
}
leaf network-id-ref {
type nw:network-id;
type leafref {
path "/nw:networks/nw:network/nw:network-id";
require-instance false;
}
description
"A reference to a network-id in base ietf-network module.";
}
......
......@@ -580,7 +580,7 @@
typedef admin-group {
type binary {
length 32;
length 32;
}
description
"Administrative group/Resource class/Color.";
......@@ -680,12 +680,18 @@
"The tunnel path hop limit.";
}
leaf metric-type {
type string;
type identityref {
base path-metric-type;
}
default path-metric-te;
description
"The tunnel path metric type.";
}
leaf tiebreaker-type {
type string;
type identityref {
base path-tiebreaker-type;
}
default path-tiebreaker-maxfill;
description
"The tunnel path computation tie breakers.";
}
......@@ -729,7 +735,9 @@
list constraints {
key "usage";
leaf usage {
type string;
type identityref {
base resource-affinities-type;
}
description "Affinities usage";
}
container constraint {
......@@ -765,7 +773,9 @@
"Type of SRLG representation";
case values {
leaf usage {
type string;
type identityref {
base route-exclude-srlg;
}
description "SRLG usage";
}
leaf-list values {
......@@ -777,7 +787,9 @@
list constraints {
key "usage";
leaf usage {
type string;
type identityref {
base route-exclude-srlg;
}
description "SRLG usage";
}
container constraint {
......@@ -829,12 +841,17 @@
source.";
}
leaf type {
type string;
type identityref {
base bidir-association-type;
}
default bidir-assoc-non-corouted;
description
"The TE tunnel association type.";
}
leaf provisioing {
type string;
type identityref {
base bidir-provisioning-mode;
}
description
"Describes the provisioning model of the
associated bidirectional LSP";
......
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type status;
description
"Identifies a network.";
}
}
typedef status {
type uint8;
}
leaf network-ref {
type leafref {
path "/networks";
}
}
}
\ No newline at end of file
......@@ -5,7 +5,7 @@ module module1 {
import module2 {
prefix "nt";
}
grouping te-node-tunnel-termination-capability {
container te-node-tunnel-termination-capability {
description
"Termination capability of a tunnel termination point on a
TE node.";
......@@ -25,4 +25,4 @@ module module1 {
}
} // termination-capability
} // te-node-tunnel-termination-capability
}
\ No newline at end of file
}
......
......@@ -5,7 +5,7 @@ module ietf-network-topology {
import ietf-network {
prefix "nt";
}
grouping te-node-tunnel-termination-capability {
container te-node-tunnel-termination-capability {
description
"Termination capability of a tunnel termination point on a
TE node.";
......@@ -25,4 +25,4 @@ module ietf-network-topology {
}
} // termination-capability
} // te-node-tunnel-termination-capability
}
\ No newline at end of file
}
......
module GroupingCopiedInModule2 {
yang-version 1;
namespace "onos-yang-19:level1:newlevel";
prefix test;
import LeafrefInGroupingOfModule1 {
prefix module1;
}
description "leaf scenario";
container value {
uses "module1:network-ref";
}
}
\ No newline at end of file
module ietf-network {
module LeafrefInGroupingOfModule1 {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
grouping input {
leaf network-id {
type string;
namespace "onos-yang-19:level1:newlevel";
prefix test2;
description "leaf scenario";
container networks {
list network {
key "network-id";
description
"Describes a network.
A network typically contains an inventory of nodes,
topological information (augmented through
network-topology model), as well as layering
information.";
container network-types {
description
"Identifies a network.";
"Serves as an augmentation target.
The network type is indicated through corresponding
presence containers augmented into this container.";
}
}
input {
leaf network-id {
type uint8;
type string;
description
"Identifies a network.";
}
}
output {
leaf network-ip {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "/networks/input/network-id";
grouping network-ref {
leaf network-ref {
type leafref {
path "/test2:networks/test2:network/test2:network-id";
}
}
}
}
\ No newline at end of file
......
module ietf-te-topology {
yang-version 1;
namespace "onos-yang-19:level1:newlevel";
prefix test;
import ietf-network {
prefix "nw";
}
description "leaf scenario";
typedef te-topology-event-type {
type enumeration {
enum "add" {
value 0;
description
"A TE node or te-link has been added.";
}
enum "remove" {
value 1;
description
"A TE node or te-link has been removed.";
}
enum "update" {
value 2;
description
"A TE node or te-link has been updated.";
}
}
description "TE Event type for notifications";
} // te-topology-event-type
container te-node-event {
leaf event-type {
type te-topology-event-type;
description "Event type.";
}
description "Notification event for TE node.";
uses nw:node-ref;
}
}
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
organization
"IETF I2RS (Interface to the Routing System) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/i2rs/>
WG List: <mailto:i2rs@ietf.org>
WG Chair: Susan Hares
<mailto:shares@ndzh.com>
WG Chair: Jeffrey Haas
<mailto:jhaas@pfrc.org>
Editor: Alexander Clemm
<mailto:alex@cisco.com>
Editor: Jan Medved
<mailto:jmedved@cisco.com>
Editor: Robert Varga
<mailto:rovarga@cisco.com>
Editor: Tony Tkacik
<mailto:ttkacik@cisco.com>
Editor: Nitin Bahadur
<mailto:nitin_bahadur@yahoo.com>
Editor: Hariharan Ananthakrishnan
<mailto:hari@packetdesign.com>";
description
"This module defines a common base model for a collection
of nodes in a network. Node definitions are further used
in network topologies and inventories.
Copyright (c) 2015 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of
draft-ietf-i2rs-yang-network-topo-02;
see the RFC itself for full legal notices.
NOTE TO RFC EDITOR: Please replace above reference to
draft-ietf-i2rs-yang-network-topo-02 with RFC
number when published (i.e. RFC xxxx).";
revision 2015-12-08 {
description
"Initial revision.
NOTE TO RFC EDITOR: Please replace the following reference
to draft-ietf-i2rs-yang-network-topo-02 with
RFC number when published (i.e. RFC xxxx).";
reference
"draft-ietf-i2rs-yang-network-topo-02";
}
typedef node-id {
type string;
description
"Identifier for a node.";
}
typedef network-id {
type string;
description
"Identifier for a network.";
}
grouping network-ref {
description
"Contains the information necessary to reference a network,
for example an underlay network.";
leaf network-ref {
type leafref {
path "/nd:networks/nd:network/nd:network-id";
require-instance false;
}
description
"Used to reference a network, for example an underlay
network.";
}
}
grouping node-ref {
description
"Contains the information necessary to reference a node.";
leaf node-ref {
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/../"+
"network-ref]/nd:node/nd:node-id";
require-instance false;
}
description
"Used to reference a node.
Nodes are identified relative to the network they are
contained in.";
}
uses network-ref;
}
container networks {
description
"Serves as top-level container for a list of networks.";
list network {
key "network-id";
description
"Describes a network.
A network typically contains an inventory of nodes,
topological information (augmented through
network-topology model), as well as layering
information.";
container network-types {
description
"Serves as an augmentation target.
The network type is indicated through corresponding
presence containers augmented into this container.";
}
leaf network-id {
type network-id;
description
"Identifies a network.";
}
list supporting-network {
key "network-ref";
description
"An underlay network, used to represent layered network
topologies.";
leaf network-ref {
type leafref {
path "/networks/network/network-id";
require-instance false;
}
description
"References the underlay network.";
}
}
list node {
key "node-id";
description
"The inventory of nodes of this network.";
leaf node-id {
type node-id;
description
"Identifies a node uniquely within the containing
network.";
}
list supporting-node {
key "network-ref node-ref";
description
"Represents another node, in an underlay network, that
this node is supported by. Used to represent layering
structure.";
leaf network-ref {
type leafref {
path "../../../supporting-network/network-ref";
require-instance false;
}
description
"References the underlay network that the
underlay node is part of.";
}
leaf node-ref {
type leafref {
path "/networks/network/node/node-id";
require-instance false;
}
description
"References the underlay node itself.";
}
}
}
}
}
container networks-state {
config false;
description
"Serves as top-level container for a list of state information
for networks";
list network {
key "network-ref";
description
"Data nodes representing operational data and state of
networks.
An instance is automatically created for every network
in the corresponding list under the networks container.";
uses network-ref;
leaf server-provided {
type boolean;
description
"Indicates whether the information concerning this
particular network is populated by the server
(server-provided true, the general case for network
information discovered from the server),
or whether it is configured by a client
(server-provided true, possible e.g. for
service overlays managed through a controller).";
}
}
}
}
module ietf-network {
module SelfResolutionWhenLeafrefInModuleReferToGroupingInModule {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
......@@ -16,4 +16,4 @@ module ietf-network {
}
}
}
}
\ No newline at end of file
}
......
module ietf-network {
module SelfResolutionWhenLeafrefInModuleReferToInvalidNode {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
......@@ -16,4 +16,4 @@ module ietf-network {
path "/define/network-id";
}
}
}
\ No newline at end of file
}
......
module topology {
yang-version 1;
namespace "onos-yang-19:level1:newlevel";
prefix test;
organization "huawei";
contact "adarsh.m@huawei.com";
description "leaf scenario";
container networks {
list network {
key "network-id";
description
"Describes a network.
A network typically contains an inventory of nodes,
topological information (augmented through
network-topology model), as well as layering
information.";
container network-types {
description
"Serves as an augmentation target.
The network type is indicated through corresponding
presence containers augmented into this container.";
}
leaf network-id {
type string;
description
"Identifies a network.";
}
}
leaf network-ip {
type uint8;
description
"Identifies a network.";
}
}
augment "/networks/network" {
container config {
description
"Configuration data.";
choice bundle-stack-level {
description
"The TE link can be partitioned into bundled
links, or component links.";
case bundle {
container bundled-links {
description
"A set of bundled links.";
reference
"RFC4201: Link Bundling in MPLS Traffic Engineering
(TE).";
list bundled-link {
key "src-tp-ref";
leaf src-tp-ref {
type leafref {
path "../../../../../network-ip";
require-instance true;
}
}
}
}
}
}
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
import ietf-inet-types {
prefix inet;
}
typedef node-id {
type inet:uri;
description
"Identifier for a node.";
}
leaf xyz {
type string;
}
typedef network-id {
type inet:uri;
description
"Identifier for a network.";
}
grouping network-ref {
description
"Contains the information necessary to reference a network,
for example an underlay network.";
leaf network-ref {
type leafref {
path "/nd:xyz";
require-instance false;
}
description
"Used to reference a network, for example an underlay
network.";
}
}
}
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
import network {
prefix "nw";
}
grouping xyz {
leaf network-id-ref {
type leafref {
path "/nw:networks/nw:network/nw:network-id";
require-instance false;
}
description
"A reference to a network-id in base ietf-network module.";
}
}
grouping yzx {
container hi {
uses xyz;
}
}
container fine {
uses yzx;
}
container networks {
leaf network {
type string;
}
}
}
module network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
organization
"IETF I2RS (Interface to the Routing System) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/i2rs/>
WG List: <mailto:i2rs@ietf.org>
WG Chair: Susan Hares
<mailto:shares@ndzh.com>
WG Chair: Jeffrey Haas
<mailto:jhaas@pfrc.org>
Editor: Alexander Clemm
<mailto:alex@cisco.com>
Editor: Jan Medved
<mailto:jmedved@cisco.com>
Editor: Robert Varga
<mailto:rovarga@cisco.com>
Editor: Tony Tkacik
<mailto:ttkacik@cisco.com>
Editor: Nitin Bahadur
<mailto:nitin_bahadur@yahoo.com>
Editor: Hariharan Ananthakrishnan
<mailto:hari@packetdesign.com>";
description
"This module defines a common base model for a collection
of nodes in a network. Node definitions are further used
in network topologies and inventories.
Copyright (c) 2015 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of
draft-ietf-i2rs-yang-network-topo-02;
see the RFC itself for full legal notices.
NOTE TO RFC EDITOR: Please replace above reference to
draft-ietf-i2rs-yang-network-topo-02 with RFC
number when published (i.e. RFC xxxx).";
revision 2015-12-08 {
description
"Initial revision.
NOTE TO RFC EDITOR: Please replace the following reference
to draft-ietf-i2rs-yang-network-topo-02 with
RFC number when published (i.e. RFC xxxx).";
reference
"draft-ietf-i2rs-yang-network-topo-02";
}
typedef node-id {
type string;
description
"Identifier for a node.";
}
typedef network-id {
type string;
description
"Identifier for a network.";
}
grouping network-ref {
description
"Contains the information necessary to reference a network,
for example an underlay network.";
leaf network-ref {
type leafref {
path "/nd:networks/nd:network/nd:network-id";
require-instance false;
}
description
"Used to reference a network, for example an underlay
network.";
}
}
grouping node-ref {
description
"Contains the information necessary to reference a node.";
leaf node-ref {
type leafref {
path "/nd:networks/nd:network[nd:network-id=current()/../"+
"network-ref]/nd:node/nd:node-id";
require-instance false;
}
description
"Used to reference a node.
Nodes are identified relative to the network they are
contained in.";
}
uses network-ref;
}
container networks {
description
"Serves as top-level container for a list of networks.";
list network {
key "network-id";
description
"Describes a network.
A network typically contains an inventory of nodes,
topological information (augmented through
network-topology model), as well as layering
information.";
container network-types {
description
"Serves as an augmentation target.
The network type is indicated through corresponding
presence containers augmented into this container.";
}
leaf network-id {
type network-id;
description
"Identifies a network.";
}
list supporting-network {
key "network-ref";
description
"An underlay network, used to represent layered network
topologies.";
leaf network-ref {
type leafref {
path "/networks/network/network-id";
require-instance false;
}
description
"References the underlay network.";
}
}
list node {
key "node-id";
description
"The inventory of nodes of this network.";
leaf node-id {
type node-id;
description
"Identifies a node uniquely within the containing
network.";
}
list supporting-node {
key "network-ref node-ref";
description
"Represents another node, in an underlay network, that
this node is supported by. Used to represent layering
structure.";
leaf network-ref {
type leafref {
path "../../../supporting-network/network-ref";
require-instance false;
}
description
"References the underlay network that the
underlay node is part of.";
}
leaf node-ref {
type leafref {
path "/networks/network/node/node-id";
require-instance false;
}
description
"References the underlay node itself.";
}
}
}
}
}
container networks-state {
config false;
description
"Serves as top-level container for a list of state information
for networks";
list network {
key "network-ref";
description
"Data nodes representing operational data and state of
networks.
An instance is automatically created for every network
in the corresponding list under the networks container.";
uses network-ref;
leaf server-provided {
type boolean;
description
"Indicates whether the information concerning this
particular network is populated by the server
(server-provided true, the general case for network
information discovered from the server),
or whether it is configured by a client
(server-provided true, possible e.g. for
service overlays managed through a controller).";
}
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
organization
"IETF I2RS (Interface to the Routing System) Working Group";
grouping node-ref {
description
"Contains the information necessary to reference a node.";
container node-from-grouping {
leaf node-ref {
type leafref {
path "/networks/network/node/node-id";
require-instance false;
}
}
}
}
container networks {
description
"Serves as top-level container for a list of networks.";
list network {
key "network-id";
description
"Describes a network.
A network typically contains an inventory of nodes,
topological information (augmented through
network-topology model), as well as layering
information.";
container network-types {
description
"Serves as an augmentation target.
The network type is indicated through corresponding
presence containers augmented into this container.";
}
leaf network-id {
type string;
description
"Identifies a network.";
}
list supporting-network {
key "network-ref";
description
"An underlay network, used to represent layered network
topologies.";
leaf network-ref {
type leafref {
path "/networks/network/network-id";
require-instance false;
}
description
"References the underlay network.";
}
}
list node {
key "node-id";
description
"The inventory of nodes of this network.";
leaf node-id {
type uint8;
description
"Identifies a node uniquely within the containing
network.";
}
list supporting-node {
key "network-ref node-ref";
description
"Represents another node, in an underlay network, that
this node is supported by. Used to represent layering
structure.";
leaf network-ref {
type leafref {
path "../../../supporting-network/network-ref";
require-instance false;
}
description
"References the underlay network that the
underlay node is part of.";
}
leaf node-ref {
type leafref {
path "/networks/network/node/node-id";
require-instance false;
}
description
"References the underlay node itself.";
}
}
}
}
uses node-ref;
}
}
module ietf-network {
module SelfResolutionWhenLeafrefInModuleReferToLeafInInputOfRpc {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
......@@ -20,4 +20,4 @@ module ietf-network {
path "/networks/input/network-id";
}
}
}
\ No newline at end of file
}
......
module ietf-network {
module SelfResolutionWhenLeafrefInModuleReferToGroupingWithInputInRpc {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
......@@ -25,4 +25,4 @@ module ietf-network {
path "/networks/input/network-id";
}
}
}
\ No newline at end of file
}
......
module ietf-network {
module SelfResolutionWhenLeafrefReferToContainerLeaf {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
......@@ -16,4 +16,4 @@ module ietf-network {
path "/networks/network-id";
}
}
}
\ No newline at end of file
}
......