how can i change a yang model into a xml or json file,when there is a union type element? - ietf-netmod-yang

'''
i want to change a yang model into xml, but there is a union type in yang model, and the odl check there is a error in the xml, i don`t known how to solve it
'''
'''
the part of yang model
leaf prefix {
type leafref {
path "../config/prefix";
}
description
"Reference to the configured prefix for this aggregate";
}
typedef ip-prefix {
type union {
type ipv4-prefix;
type ipv6-prefix;
}
description
"An IPv4 or IPv6 prefix.";
}
'''
'''
the part of xml
<prefix>10.0.0.0/24</prefix>
'''
'''
the error msg
<errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<error>
<error-type>protocol</error-type>
<error-tag>malformed-message</error-tag>
<error-message>Error parsing input: Invalid value ""10.0.0.0/24"" for union type.</error-message>
<error-info>Invalid value ""10.0.0.0/24"" for union type.</error-info>
</error>
</errors>
'''

This seems unrelated with the fact that this is a union.
The prefix parameter has several rules in this case:
It is a leafref, meaning the value you provide (10.0.0.0/24) must exist as an existing config/prefix.
The value also needs to match either the ipv4-prefix or the ipv6-prefix. Each of these are strings with specific regex.
For this particular case, the value you've provided looks like a valid ipv4-prefix.
In short, most likely the error is related with the fact that the leafref constraint is not being followed.
I'd need to see the actual XML being sent in order to know the error root-cause.

Related

Is it possible to use two When statements in a Yang model

Trying to use one Yang leaf with two different if-types depending on the value given.
Currently have:
leaf interface_number {
when "boolean(string(/payload/interface_type) != 'ae')";
type isyt:interface_number_value;
when "boolean(string(/payload/interface_type) == 'ae')";
type isyt:interface_lag_value;
description
"Interface Number. Example value: 1/1/1 or 11 for LAG";
mandatory "true";
}
I have also tried:
leaf interface_number {
when "boolean(string(/payload/interface_type) != 'ae')" {
type isyt:interface_number_value;
}
when "boolean(string(/payload/interface_type) == 'ae')" {
type isyt:interface_lag_value;
}
description
"Interface Number. Example value: 1/1/1 or 11 for LAG";
mandatory "true";
}
Yang seems to accept the first when they errors on the second when statements' boolean.
Is this even possible? or is there a better method to use for this.
That's not how the YANG syntax works; the type statement cannot be conditional upon the when. The when affects the whole enclosing node, so if it evaluates to false, your interface_number would not be valid at all.
What you can do here is to create a choice whose case statements are when-conditional depending on the type of the ../interface_type leaf. This will need a different name for each of the leaf that you define within these case statements.

NDepend: Find fields that are either a given type or use a given type in their generic parameters

How would I go about using NDepend to not only identify JustMyCode.Fields that are exactly a given type, but also indirectly, i.e. fields like IList<MyType>, IDictionary<int, MyType>, Lazy<T> and all those "nice" generic variants/usages?
Is there any helper method similar to .UsedBy(...) available by any chance that provides such a functionality?
Here is a query to get field typed with String or Int32:
let types = Types.WithFullNameIn(
"System.String",
"System.Int32").ToArray()
from f in Application.Fields
where !f.ParentType.IsEnumeration &&
f.FieldType != null &&
types.Contains(f.FieldType)
select new { f, type =f.FieldType }
For now you cannot detect when a type is used in a generic parameter.

How to enumerate over columns with tokio-postgres when the field types are unknown at compile-time?

I would like a generic function that converts the result of a SQL query to JSON. I would like to build a JSON string manually (or use an external library). For that to happen, I need to be able to enumerate the columns in a row dynamically.
let rows = client
.query("select * from ExampleTable;")
.await?;
// This is how you read a string if you know the first column is a string type.
let thisValue: &str = rows[0].get(0);
Dynamic types are possible with Rust, but not with the tokio-postgres library API.
The row.get function of tokio-postgres is designed to require generic inference according to the source code
Without the right API, how can I enumerate rows and columns?
You need to enumerate the rows and columns, doing so you can get the column reference while enumerating, and from that get the postgresql-type. With the type information it's possible to have conditional logic to choose different sub-functions to both: i) get the strongly typed variable; and, ii) convert to a JSON value.
for (rowIndex, row) in rows.iter().enumerate() {
for (colIndex, column) in row.columns().iter().enumerate() {
let colType: string = col.type_().to_string();
if colType == "int4" { //i32
let value: i32 = row.get(colIndex);
return value.to_string();
}
else if colType == "text" {
let value: &str = row.get(colIndex);
return value; //TODO: escape characters
}
//TODO: more type support
else {
//TODO: raise error
}
}
}
Bonus tips for tokio-postgres code maintainers
Ideally, tokio-postgres would include a direct API that returns a dyn any type. The internals of row.rs already use the database column type information to confirm that the supplied generic type is valid. Ideally a new API uses would use the internal column information quite directly with improved FromSQL API, but a simpler middle-ground exists:-
It would be possible for an extra function layer in row.rs that uses the same column type conditional logic used in this answer to then leverage the existing get function. If a user such as myself needs to handle this kind of conditional logic, I also need to maintain this code when new types are handled by tokio-postgresql, therefore, this kind of logic should be included inside the library where such functionality can be better maintained.

Ontology annotation type is missing in saved ontology file

I'm using OWL API 4.1. I add annotation with type XSD:string like that:
OWLAnnotationProperty annotationProperty = this.getDf().getOWLAnnotationProperty(annotationPropertyIri);
OWLLiteral lit = this.df.getOWLLiteral(annotationValue, range);
OWLAnnotation annotation = df.getOWLAnnotation(annotationProperty, lit);
this.getMng().applyChange(new AddOntologyAnnotation(this.getOnt(), annotation));
... I checked that here lit="test"^^xsd:string. But after I saved ontology (in ttl format) - there in no type ending - ^^xsd:string:
...
<http://semanticweb.rocks/whole-dataset-name/wheat-02> a owl:Ontology ;
dc:description """test""" ;
dc:source """http://mail.ru"""^^xsd:anyURI .
...
If I use other type (e.g. xsd:anyURI ) instead of ^^xsd:string the ending ^^xsd:anyURI is presented.
What is matter with ^^xsd:string?
The xsd:string type can be skipped for string literals, when there is no language tag. A literal typed with xsd:string is identical to a plain literal with no language tag.
If you load the ontology back into an OWLOntology, I expect you to see a test^^xsd:string literal attached to the ontology.

OclInEcore: operation return type issue

I want to write the following operation in the oclInEcore editor in the context of the "Comp" class, which is supposed to collect the parents of a Comp object to a Set.
operation parents(): Set(Comp)
{
body: self.superComp->union(self.parents());
}
The problem is, that ocl doesn't accept Set(Comp) as return type. However, it accepts Comp[*], but this will end up in an invalid call (Because of the incompatible return types, I suppose...)
The Set(Comp) is indeed invalid. In OCLInEcore the syntax for specifying the return type is different. The thing is that the model structure definitions (classes, features, operations) have nothing to do with OCL itself. It only comes later when you define the actual logic for your invariants, derived features or operation bodies.
The correct way of doing this is following:
operation parents() : Comp[*] { <properties> derived }
The Comp is the return type and the [*] sets the upperBound to -1.
The <properties> is a list of the operation return type properties that will precisely specify wich of the collection class should be used.
Here are the options:
!unique ordered --> Sequence(Comp)
!unique !ordered --> Bag(Comp)
unique !ordered --> Set(Comp)
unique ordered --> OrderedSet(Comp)
For example:
operation parents() : Comp[*] { unique !ordered derived }
will result in the Set(Comp).
I don't know the oclInEcore, but in base ecore you can define an EDataType and set its "Instance Type Name" to the Java return type you want and then use that Data Type on your EOperation. HTH.