Yang type not found - data-modeling

There is not too many questions about YANG models here in stackoverflow, but I hope you can help me out.
I have created a YANG model and I want to import it into another module. The import statement is like this:
import service-abstract-type-definition {
prefix sfc-satd;
revision-date 2015-11-15;
}
And the usage of it looks like this:
leaf abstract-type {
type sfc-satd:service-abstract-type-definition;
description
"Abstract Type definition for the Service Function";
}
This leaf is inside a grouping.
The imported module looks like this:
module service-abstract-type-definition {
namespace "urn:odl:params:xml:ns:yang:sfc-satd";
prefix sfc-satd;
import service-locator {
prefix sfc-sl;
revision-date 2014-07-01;
}
description
"This module contains YANG definitions for managing Service Abstract Type Definition";
revision 2015-11-15 {
description
"First version of Service Abstract Type Definition.";
}
// Service Function
// Service Abstract Type definitions
container service-abstract-type-definition {
description
"List of parameters to define an abstract type of Service Function";
leaf name {
type string;
description "Service Function type names such as firewall, dpi, tcp-proxy, etc";
}
leaf symmetry {
type boolean;
description "SF is involved in a symmetric service path";
}
leaf bidirectionality {
type boolean;
description "SF handles uplink and downlink traffic";
}
leaf nsh-aware {
type boolean;
description "Service Function can handle Network Service Headers";
}
container dpl {
description "Data Plane Locators from the Service Function";
uses sfc-sl:data-plane-locator;
}
}
}
When compiling I get the ERROR saying
type satd:service-abstract-type-definition is not found
and I really don't get it. Any idea?
Thanks

You generally use import statements for two reasons in NETMOD YANG 1.0: reusing top-level definitions from another module and injecting definitions from your module into another module.
There are five top-level definitions that may be imported from another module in YANG: groupings, typedefs, extensions, features and identities. In your case you were trying to import a definition that is not one of those - a YANG container, which represents one of the data definition statements (they define nodes that may be instantiated AKA the data tree). The other data definition statements are: leaf, leaf-list, list, choice, case, augment, uses, and anyxml.
You cannot import data definition statements for use in your module, unless they are defined within a grouping and referenced with the uses statement. Furthermore, the leaf statement's type child statement represents the data type of a leaf instance, which restricts the set of valid values for the instance's value (the set of values for the text node of an XML element in XML encoding for example). Leaf statements also cannot be parents to other data definition statements - that is why they are called leafs (a data tree branch ends with them).
The term type in YANG is more like the data types in programming languages and should not be confused with certain terms from other schema languages (complex types), which define structure. Like you found out yourself, you may define custom data types in YANG by using the typedef statement.

Related

TypeScript Discriminated Union with Optional Discriminant

I've created a discriminated union that's later used to type props coming into a React component. A pared down sample case of what I've created looks like this:
type Client = {
kind?: 'client',
fn: (updatedIds: string[]) => void
};
type Server = {
kind: 'server',
fn: (selectionListId: string) => void
};
type Thing = Client | Server;
Note that the discriminant, kind, is optional in one code path, but is defaulted when it is destructured in the component definition:
function MyComponent(props: Thing) {
const {
kind = 'client',
fn
} = props;
if (kind === 'client') {
props.fn(['hey']);
// also an error:
// fn(['hey'])
} else {
props.fn('hi')
// also an error:
// fn('hey')
}
}
What I'm trying to understand is what's going on with this conditional. I understand that the type checker is having trouble properly narrowing the type of Thing, since the default value is separate from the type definition. The oddest part is that in both branches of the conditional it insists that fn is of type (arg0: string[] & string) => void and I don't understand why the type checker is trying to intersect the parameters here.
I would have expected it to be unhappy about non-exhaustiveness of the branches (i.e. not checking the undefined branch) or just an error on the else branch where the 'server' and undefined branches don't line up. But even trying to rearrange the code to be more explicit about each branch doesn't seem to make any impact.
Perhaps because the compiler simply can't narrow the types so tries an intersection so it doesn't matter which path--if the signatures are compatible then it's fine to call the function, otherwise you basically end up with a never (since string[] & string is an impossible type)?
I understand that there are a variety of ways I can resolve this via user-defined type predicates or type assertions, but I'm trying to get a better grasp on what's going on here internally and to find something a bit more elegant.
TS Playground link
It's an implementation detail in TS. Types are not narrowed when you are storing the value in a different variable. The same issue exists for the square bracket notation. You can refer to this question, it deals with a similar issue. Apparently, this is done for compiler performance.
You can fix your issue by using both props.fn and props.kind.
playground
Or write a type guard function.

How can i create a custom object in Salesforce with a '__' in the name?

I am trying to check if a change tables exists in Salesforce by calling
var name = "acme_npsp__Allocation_c__c";
try
{
salesforceObject = _service.describeSObject(name);
return sObject;
}
catch (Exception ex)
{
error = ex.Message;
}
but it gives an error:
INVALID_TYPE: salesforceObject type 'acme_npsp__Allocation_c__c' is not
supported. If you are attempting to use a custom object, be sure to append the
'__c' after the entity name. Please reference your WSDL or the describe call for
the appropriate names.
(107 - FIELD_INTEGRITY_EXCEPTION) Cannot create a new component with the namespace: acme_npsp. Only components in the same namespace as the organization can be created through the API.
But if i replace the __ in the middle with a single _ it seems to work , but that isnt my object in salesforce so i cant reference it in other code.
Salesforce doesnt allow to create such an object with '__' in the middle, but it was created using the package Nonprofit Success Pack (NPSP) which can be downloaded from the store.
How can i create the object with the '__' in the middle , ie after the npsp ?
Salesforce does not allow __ in API names, because double underscores serve a special meaning: they delimit the components of the API name. An API name, for a schema element like this, consists of up to 3 parts:
namespace__component_name__c
namespace is the first component, and is the (optional) namespace, which indicates that the component is part of a package. NPSP's namespace is npsp. You cannot create components in a namespace you do not own.
The name element is present on all components. For Account and other standard objects, it's the entire API name.
__c is the suffix, which indicates what kind of entity you have. __c is a custom object; __b a BigObject; __e a custom Platform Event; __mdt a custom Metadata Type. Lack of a suffix indicates a standard component.
Your question does not make much sense as written. You appear to be trying to work with the object npsp__Allocation__c. It's not clear why you are trying to prepend some other value to the namespace and suffix.
Accessing the describe does not create an object, so the behavior of your code is exactly as designed.

Is there any way to use flow to restrict specific string patterns?

I'm using Flow on a React webapp and I'm currently facing a use-case where I'm asking for the user to input certain time values in a "HH:mm" format. Is there any way to describe what pattern is being followed by the strings?
I've been looking around for a solution but the general consensus which I agree to to a certain point seems to be that you don't need to handle this kind of thing using Flow, favouring using validating functions and relying on the UI code to supply the code following the correct pattern. Still, I was wondering if there is any way to achieve this in order to make the code as descriptive as possible.
You want to create a validator function, but enhanced using Opaque Type Aliases: https://flow.org/en/docs/types/opaque-types/
Or, more specifically, Opaque Type Aliases with Subtyping Constraints: https://flow.org/en/docs/types/opaque-types/#toc-subtyping-constraints
You should write a validator function in the same file where you define the opaque type. It will accept the primitive type as an argument and return a value typed as the opaque type with subtyping constraint.
Now, in a different file, you can type some variables as the opaque type, for example in function arguments. Flow will enforce that you only pass values that go through your validator function, but these could be used just as if they were the primitive type.
Example:
exports.js:
export opaque type ID: string = string;
function validateID(x: string): ID | void {
if ( /* some validity check passes */ ) {
return x;
}
return undefined;
}
import.js:
import type {ID} from './exports';
function formatID(x: ID): string {
return "ID: " + x; // Ok! IDs are strings.
}
function toID(x: string): ID {
return x; // Error: strings are not IDs.
}

Represent Adobe's array-like collections in TypeScript

Adobe's ExtendScript features Number-indexed collections, for example the ArtLayers type. document.artLayers[0] might get me the first ArtLayer in the present document. ArtLayers also has a number of miscellaneous fields and methods. How can I best represent this type in a .d.ts file?
A definition for ExtendScript can already be found here. I looked at it and it does not seem perfect, but it could be a starting/reference point.
If I had to write a type as you describe it, I would probably use something like this:
interface ArtLayers {
length: number;
[index: number]: ArtLayer;
parent: Document
typename: string
add(): void
getByName(name: string): void
removeAll(): void
}

SystemVerilog: How to create an interface which is an array of a simpler interfaces?

I'm attempting to create an interface that is an array of a simpler interface. In VHDL I could simply define two types, a record and an array of records. But how to do this in SystemVerilog? Here's what I've tried:
`define MAX_TC 15
...
interface scorecard_if;
score_if if_score [`MAX_TC];
endinterface
interface score_if;
integer tc;
integer pass;
integer fail;
bit flag_match;
real bandwidth;
endinterface
But I get an error from Aldec Active-HDL:
Error: VCP2571 TestBench/m3_test_load_tb_interfaces.sv : (53, 34):
Instantiations must have brackets (): if_score.
I also tried
interface scorecard_if;
score_if [`MAX_TC] if_score;
endinterface
and
interface scorecard_if;
score_if [`MAX_TC];
endinterface
but both of those just resulted in "Unexpected token" syntax errors.
Is it even possible to do this? There are two workarounds that I can think of if there isn't a way to do this. First I could define all the individual elements of score_if as unpacked arrays:
interface score_if;
integer tc [1:`MAX_TC];
integer pass [1:`MAX_TC];
integer fail [1:`MAX_TC];
bit flag_match [1:`MAX_TC];
real bandwidth [1:`MAX_TC];
endinterface
This compiles, but it's ugly in that I can no longer refer to a single score as a group.
I might also be to instantiate an array of score_if (using the original code), but I really want to instantiate scorecard_if inside a generate loop that would allow me instantiate a variable number of scorecard_if interfaces based on a parameter.
Just to provide a bit of explanation of what I'me trying to do, score_if is supposed to be a record of the score for a given test case, and scorecard_if an array for all of the test cases. But my testbench has multiple independent stimulus generators, monitors and scorecards to deal with multiple independent modules inside the DUT where the multiple is a parameter.
Part 1 : Declaring an array of interfaces
Add parentheses to the end of the interface instantiation. According to IEEE Std 1800-2012, all instantiations of hierarchical instances need the parentheses for the port list even if the port list is blank. Some tools allow dropping the parentheses if the interfaces doesn't have any ports in the declaration and and the instantiation is simple; but this is not part of the standard. Best practice is to use parentheses for all hierarchical instantiation.
Solution:
score_if if_score [`MAX_TC] () ;
Syntax Citations:
§ 25.3 Interface syntax & § A.4.1.2 Interface instantiation
interface_instantiation ::= // from A.4.1.2
interface_identifier [ parameter_value_assignment ] hierarchical_instance { , hierarchical_instance } ;
§ A.4.1.1 Module instantiation
hierarchical_instance ::= name_of_instance ( [ list_of_port_connections ] )
Part 2: Accessing elements for that array
Hierarchical references must be constant. Arrayed hierarchical instances cannot be accessed by dynamic indexes. It is an rule/limitation since at least IEEE Std 1364. Read more about it in IEEE Std 1800-2012 § 23.6 Hierarchical names, and the syntax rule is:
hierarchical_identifier ::= [ $root . ] { identifier constant_bit_select . } identifier
You could use a generate-for-loop, as it does an static unroll at compile/elaboration time. The limitation is you cannot use your display message our accumulate your fail count in the loop. You could use the generate loop to copy data to a local array and sum that, but that defeated your intention.
An interface is normally a bundle of nets used to connect modules with class-base test-bench or shared bus protocols. You are using it as a nested score card. A typedef struct would likely be better suited to your purpose. A struct is a data type and does not have the hierarchical reference limitation as modules and interfaces. It looked like you were already trying rout in your previous question. Not sure why you switched to nesting interfaces.
It looks like you are trying to create a fairly complex test environment. If so, I suggest learning UVM before spending to much time reinventing for a advance testbench architecture. Start with 1.1d as 1.2 isn't mainstream yet.
This also works:
1. define a "container" interface:
interface environment_if (input serial_clk);
serial_if eng_if[`NUM_OF_ENGINES](serial_clk);
virtual serial_if eng_virtual_if[`NUM_OF_ENGINES];
endinterface
2. in the testbench instantiate env_if connect serial_if with generate, connect the virtual if with the non virtual and pass the virtual if to the verification env:
module testbench;
....
environment_if env_if(serial_clk);
.....
dut i_dut(...);
genvar eng_idx
generate
for(eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++) begin
env_if.eng_if[eng_idx].serial_bit = assign i_dut.engine[eng_idx].serial_bit;
end
endgenerate
......
initial begin
env_if.eng_virtual_if = env_if.eng_if[0:`NUM_OF_ENGINES-1];
//now possible to iterate over eng_virtual_if[]
for(int eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++)
uvm_config_db#(virtual serial_if)::set(null, "uvm_test_top.env", "tx_vif", env_if.env_virtual_if[eng_idx]);
end
endmodule

Resources