alternative way to use boolean container - ietf-netmod-yang

container first{
container second{
type boolean;
}
}
how can i do something like this.(My error:i can't boolean a container/error: unexpected keyword "type") I don't want to use leaf. Is there an alternative ?

As per RFC 6020. For storing single data we have to use leaf. Using containers to store boolean data, I don't think would be possible.
As per RFC6020 section 7.5.1, Containers are used to organize the hierarchy of data nodes, and those whose presence in the configuration has an explicit meaning.It means we can't use container to store the data.
If you don't want to use boolean then you can try to use "enum" like this:
leaf myenum {
type enumeration {
enum zero {
value 0;
}
enum one {
value 1;
}
}
}
.

Related

Dart type_test_with_non_type when storing type in variable

In my Flutter app I want to build this function:
bool isValidType(element, Type cls) {
return element is cls;
}
The issue with this is: The name 'cls' isn't a type and can't be used in an 'is' expression. Try correcting the name to match an existing type. dart(type_test_with_non_type)
element is dynamic, but I expect it to be an Object of a class that extends the class Element (like class Node extends Element). The way I want to be able to use this function is:
isValidType(node, Node) -> true
isValidType(node, Element) -> true
I first thought I could do this:
bool isValidType(element, Type cls) {
return element.runtimeType == cls;
}
But the problem with that is that for the examples provided above it returns the following:
isValidType(node, Node) -> true
isValidType(node, Element) -> false
The reason is of course that the runtimeType of node is Node and not Element.
What do I have to change in the function provided first to work for my requirements?
There currently isn't much you can do with a Type object. The general recommendation is to avoid using them.
In your case, if you want to check against types known at compilation-time, you could make isValidType a generic function instead:
bool isValidType<T>(dynamic element) => element is T;
and then use isValidType<Node>(node) or isValidType<Element>(node). However, I don't think such a function adds anything, so you might as well replace isValidType<Node>(Node) with node is Node at the callsite.

How to augment list from one module to another and add leafs YANG

Suppose I have two modules, I would like to extend one list with new leafs.
module A {
list deviceList {
key name;
leaf name{
}
leaf hostname{
}
}
}
and I would like to augment it to another leaf
module B {
list generalInfo{
key customerName;
leaf customerName{
type string;
}
augment moduleA:deviceList {
leaf ipAddress{
}
}
}
I have done it using grouping and container and list inside but this completely changes our existing structure, I would like to ommit container and grouping if thats possible.
It seems that you want to reuse a part of the schema definition, put it in another place in the schema tree and add a node to it.
You cannot do it the way you tried because the augment statement can appear only on the root level or in the uses statement.
You can do that only with a grouping but you can omit the container. Refactor A: define a grouping that's a list. Refer to it in B and augment it.
module A {
grouping devices {
list deviceList {
key name;
leaf name{
}
leaf hostname{
}
}
}
uses devices;
}
module B {
list generalInfo{
key customerName;
leaf customerName{
type string;
}
uses moduleA:devices {
augment "deviceList" {
leaf ipAddress{
}
}
}
}
}
Note that if you use the augment statement in the module B then it means that any device implementing module B has to also implement module A and its root-level list deviceList. See RFC 7950 4.2.8:
When a server implements a module containing an "augment" statement,
that implies that the server's implementation of the augmented module
contains the additional nodes.
I am not sure if this is what you want. If not, then move the grouping definition to a module that contains only grouping definitions (without any "data definition statements") and import it from both A and B.

How to write to an Element in a Set?

With arrays you can use a subscript to access Array Elements directly. You can read or write to them. With Sets I am not sure of a way to write its Elements.
For example, if I access a set element matching a condition I'm only able to read the element. It is passed by copy and I can't therefore write to the original.
For example:
columns.first(
where: {
$0.header.last == Character(String(i))
}
)?.cells.append(value: addValue)
// ERROR: Cannot use mutating member on immutable value: function call returns immutable value
You can't just change things inside a set, because of how a (hash) set works. Changing them would possibly change their hash value, making the set into an invalid state.
Therefore, you would have to take the thing you want to change out of the set, change it, then put it back.
if var thing = columns.first(
where: {
$0.header.last == Character(String(i))
}) {
columns.remove(thing)
thing.cells.append(value: addValue)
columns.insert(thing)
}
If the == operator on Column doesn't care about cells (i.e. adding cells to a column doesn't suddenly make two originally equal columns unequal and vice versa), then you could use update instead:
if var thing = columns.first(
where: {
$0.header.last == Character(String(i))
}) {
thing.cells.append(value: addValue)
columns.update(thing)
}
As you can see, it's quite a lot of work, so maybe sets aren't a suitable data structure to use in this situation. Have you considered using an array instead? :)
private var _columns: [Column]
public var columns : [Column] {
get { _columns }
set { _columns = Array(Set(newValue)) }
// or any other way to remove duplicate as described here: https://stackoverflow.com/questions/25738817/removing-duplicate-elements-from-an-array-in-swift
}
You are getting the error because columns might be a set of struct. So columns.first will give you an immutable value. If you were to use a class, you will get a mutable result from columns.first and your code will work as expected.
Otherwise, you will have to do as explained by #Sweeper in his answer.

Yang Model recursive search for must condition

I have a problem with a restriction on my CLI. I've been investigating yang RFC7950 (https://www.rfc-editor.org/rfc/rfc7950) but I've found nothing.
Here is an example.
grouping httpGroup {
list http-list{
key "value";
leaf value {
status current { yexte:preliminary; }
description "value to match";
must "(not(../protocol)) and (not(../network-port)))" {
error-message "Not compatible with protocol or non-TCP ports";
}
type string { length "1..255"; }
}
}
}
This group will be included in several groups with the following structure:
list and {
leaf-list protocol { ..... }
uses A;
list or {
leaf-list protocol { ..... }
uses A;
}
}
grouping A {
status{}
leaf-list protocol { ..... }
leaf-list X { ..... }
uses httpGroup;
}
I need this must condition included in httpGroup to verify that protocol value has not been configured in any level of the hierarchy.
I've made this be adding more relatives paths to search for this node:
// same level
not(../protocol)
// next level
not(../and/protocol)
not(../or/protocol)
// previous level
not(../../protocol)
not(../../protocol)
//recursively down previous level
not(../../and/protocol)
not(../../or/protocol)
// third level
not(../and/or/protocol)
not(../and/and/protocol)
As you can see, this is not a clean solution at all.
Is there any way it can be done for a whole hierarchy like:
if protocol node exists and http-list exists then error.
Thank you in advance.
Groupings are meant to be reusable. It is a bad practice to attempt to create a grouping that may only be used in specific contexts. This is exactly what happens if you define an XPath expression within a grouping and this expression references nodes that are "outside" this grouping (a not yet known ancestor data node, for example, or even worse - an ancestor with a specific name).
The proper way for you to handle this situation would be to use a refine statement in each different context where this grouping is used. You target the value leaf with it, then refine it by adding a must statement, the expression of which of course depends on usage context. You do not define a must statement within grouping http-list.
Within grouping A:
grouping A {
status{}
leaf-list protocol { ..... }
leaf-list X { ..... }
uses httpGroup {refine "http-list/value" {must "not(../../protocol)";}}
}
As you can see, grouping A is now completely self-sufficient and may be used within any context - the must will not have any problems with it.

Polymorphism in Object construction

I want to create specific Object according to the type argument.
Pseudo code looks like this.
sub new {
my $type = shift;
if($type eq "S1") {$interface = X->new(); }
if($type eq "S2") {$interface = Y->new(); }
etc...
return $interface;
}
Options might be:
Substitute "package" name with $type argument. Requires package name coordination with $type.
Use Hash{S1 => X} in the Master constructor to select Value according to $type passed. Requires Hash maintenance when adding new
Object types.
I don't like any of above. Looking trully polimorphic way to accomplish that.
Thank You,
k
Your best option would likely be to use a factory pattern. A factory method takes the parameters for creating an instance of your class, then decides which object to instantiate and return from that. This can also make dependency injection easier for testing.
You'd probably be looking at something like this (in Java-esque code), with an employee object:
public class EmployeeFactory
{
public static create(String type)
{
switch (type) {
case type1:
return new EmployeeTypeOne();
case type2:
return new EmployeeTypeTwo();
default:
throw new Exception("Unrecognized type");
}
}
}
Your employees would inherit from a common interface or abstract class. You can use the factory to handle constructor parameters as well if you prefer, just try to keep things fairly reasonable (don't pass a million parameters - the factory should internally handle complex objects)
See http://refactoring.com/catalog/replaceConstructorWithFactoryMethod.html for more information.
You might like Module::PluginFinder for that. Create all your specific types in a specific namespace and give them each some identifying (constant? sub?) that the main dispatcher will then use to identify which class handles a given type.