References

Example from documentation

UML diagram for example edge rule

ExampleEquivalent Example
Example Edge Rule
{
“from”: “tenant”,
“to”: “vserver”,
“label”: “owns”,
“direction”: “OUT”,
“multiplicity”: “One2Many”,
“contains-other-v”: “${direction}”,
“delete-other-v”: “NONE”,
“SVC-INFRA”: “!${direction}”,
“prevent-delete”: “${direction}”
}
Equivalent Edge Rule
{
“from”: “vserver”,
“to”: “tenant”,
“label”: “owns”,
“direction”: “IN”,
“multiplicity”: “One2Many”,
“contains-other-v”: “!${direction}”,
“delete-other-v”: “NONE”,
“SVC-INFRA”: “${direction}”,
“prevent-delete”: “!${direction}”
}
How to read in/out/direction
How to read "from"/"to" and "direction" in this case:
- the "in" node is "vserver"
- the "out" node is "tenant"

How to read the label
How to read the "label" in this case:
- ("out" node) "label" ("in" node)

i.e. tenant "owns" vserver

How to read multiplicity
How to read "multiplicity" in this case:
- ("in" node) cardinality is "one"
- ("out" node) cardinality is "many"

i.e.
Each "tenant" has one "vserver"
Each "vserver" has many "tenants"

How to read contains-other-v
How to read "contains-other-v" in this case:
- fetching data for ("out" node) includes data for ("in" node)

i.e. fetching data for "tenant" includes data for "vserver"

How to read delete-other-v
How to read "delete-other-v" in this case:
- delete of ("out" node) includes does nothing to ("in" node)

i.e. delete of "tenant" includes does nothing to "vserver"

How to read SVC-INFRA
How to read "SVC-INFRA" in this case:
- when running edge-tag-query on ("in" node) traverse to ("out" node) and continue

i.e.
when running edge-tag-query on "vserver" traverse to "tenant" and continue

How to read prevent-delete
How to read "prevent-delete" in this case:
- prevent delete of ("out" node) when related to ("in" node), allow delete of ("in" node)

i.e.
prevent delete of "tenant" when related to "vserver", allow delete of "vserver"


General Applicability

  • EdgeRules only apply to "relationship-list" relations in the schema, since the referenced object could be anything
  • EdgeRules do not apply to sub-component relations in the schema, since this is implicit and hard-coded behaviour


FieldValuesNotes
from

(literal string as entered in EdgeRule file)


Expected to match the "name" value of "xml-root-element" in OXM file.

Note that the "from|to" pair is normalised in the code according to alphabetical order, so that "cousin pairs" with the "to|from" ordering in the EdgeRule are also grouped together, e.g.

  • from "l-interface" to "logical-link" → "l-interface|logical-link"
  • from "logical-link" to "l-interface" → "l-interface|logical-link"

Also note that the hyphens "-" are removed from the names before comparison, so the following would be equivalent:

  • l-interface
  • linter-face
to

(literal string as entered in EdgeRule file)


Expected to match the "name" value of "xml-root-element" in OXM file.

Note that the "from|to" pair is normalised in the code according to alphabetical order, so that "cousin pairs" with the "to|from" ordering in the EdgeRule are also grouped together, e.g.

  • from "l-interface" to "logical-link" → "l-interface|logical-link"
  • from "logical-link" to "l-interface" → "l-interface|logical-link"

Also note that the hyphens "-" are removed from the names before comparison, so the following would be equivalent:

  • l-interface
  • linter-face
label

(literal string as entered in EdgeRule file)


By convention, appears to be one of:

  • isA

  • org.onap.relationships.inventory.AppliesTo

  • org.onap.relationships.inventory.BelongsTo

  • org.onap.relationships.inventory.BridgedTo

  • org.onap.relationships.inventory.ComposedOf

  • org.onap.relationships.inventory.DependsOn

  • org.onap.relationships.inventory.Destination

  • org.onap.relationships.inventory.ForwardsTo

  • org.onap.relationships.inventory.IsA

  • org.onap.relationships.inventory.LocatedIn

  • org.onap.relationships.inventory.MemberOf

  • org.onap.relationships.inventory.network.MemberOf

  • org.onap.relationships.inventory.PartOf

  • org.onap.relationships.inventory.Source

  • org.onap.relationships.inventory.Targets

  • org.onap.relationships.inventory.Uses

  • startsWith

  • tosca.relationships.AttachesTo

  • tosca.relationships.HostedOn

  • tosca.relationships.network.BindsTo

  • tosca.relationships.network.LinksTo

direction
  • IN
  • OUT
  • NONE (default value used when Tinkerpop Direction is null)
  • BOTH (default value used when string is unrecognised)

Based on and extended from https://tinkerpop.apache.org/javadocs/3.3.2/core/org/apache/tinkerpop/gremlin/structure/Direction.html

Comparison is case-sensitive

multiplicity
  • Many2Many
  • One2Many
  • One2One
  • Many2One (default value used when string is unrecognised)
Comparison ignores case
contains-other-v
  • IN
  • OUT
  • BOTH
  • NONE
  • ${direction}
  • !${direction}

This is an "edge property" that applies for traversal to the other vertex.

Comparison is case-sensitive

Note that "opposite" means:

  • IN → OUT
  • OUT → IN
  • BOTH → BOTH
  • NONE → BOTH


delete-other-v
  • IN
  • OUT
  • BOTH
  • NONE
  • ${direction}
  • !${direction}

This is an "edge property" that applies for traversal to the other vertex.

Comparison is case-sensitive

Note that "opposite" means:

  • IN → OUT
  • OUT → IN
  • BOTH → BOTH
  • NONE → BOTH
SVC-INFRA
  • IN
  • OUT
  • BOTH
  • NONE
  • ${direction}
  • !${direction}

This is an "edge property" that applies for traversal to the other vertex.

Comparison is case-sensitive

Note that "opposite" means:

  • IN → OUT
  • OUT → IN
  • BOTH → BOTH
  • NONE → BOTH
prevent-delete
  • IN
  • OUT
  • BOTH
  • NONE
  • ${direction}
  • !${direction}

This is an "edge property" that applies for traversal to the other vertex.

Comparison is case-sensitive

Note that "opposite" means:

  • IN → OUT
  • OUT → IN
  • BOTH → BOTH
  • NONE → BOTH
default
  • true
  • false (default value used when string is unrecognised)


Default EdgeRule will apply when no other more specific rule applies ?

Based on https://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#valueOf(java.lang.String)

Comparison ignores case

description

(literal string as entered in EdgeRule file)


Optional for backwards compatibility with v12 and earlier (default value is empty string)

The EdgeRule JSON format does not permit comments (presence of comments appears to make the parser skip entries in the file).

Questions

  1. Is there a way to find/remove the unused/redundant EdgeRules from the json file?
  2. Is there any plan to simplify EdgeRules into an unambiguous canonical form (might be easier to read and write correctly)?
  3. How does the "default" property actually work? In v13, there are 226 EdgeRules with 224 having default "true" and 2 having default "false".


9 Comments

  1. Label should be defined by TOSCA models and is intended to be generated from SDC, similarly for both OXM file and EdgeRule file.

    Direction "IN" is deprecated. Current preference is to use Direction "OUT" for all EdgeRules. There was a bulk rewriting exercise which flipped all EdgeRules to the Direction.

    SVC-INFRA is deprecated. Refers to a type of query no longer used.

    default is used when there are multiple EdgeRules between same pair of classes, e.g. link having 2 interfaces (source and sink)

    When "contains-other-v" is "NONE", then it means "cousin" relationship and the other vertex data appears in the "relationship-list" part of the schema.

    When "contains-other-v" is "IN" or "OUT", then it means "contains" relationship and the other vertex data appears as an embedded element in the schema. This only affects the presentation of the data in the API; the storage in the graph database is unchanged.

    Direction "BOTH" is not used. The vertexes can be traversed from either end of the edge anyway.


    1. Regarding the behaviour of "contains-other-v" and its effect on the schema definition, I found a reasonably small example for vpls-pe:

      OXM Schema snippet
      		<java-type name="VplsPe">
      			<xml-root-element name="vpls-pe" />
      			<java-attributes>
                   ... (snipped) ...
      
      				<xml-element java-attribute="relationshipList" name="relationship-list" type="inventory.aai.onap.org.v14.RelationshipList" />
      				<xml-element java-attribute="pInterfaces" name="p-interfaces" type="inventory.aai.onap.org.v14.PInterfaces" />
      				<xml-element java-attribute="lagInterfaces" name="lag-interfaces" type="inventory.aai.onap.org.v14.LagInterfaces" />
      			</java-attributes>
      		</java-type>

      The EdgeRules for vpls-pe are:

      EdgeRule JSON snippet
      		{
      			"from": "lag-interface",
      			"to": "vpls-pe",
      			"label": "tosca.relationships.network.BindsTo",
      			"direction": "OUT",
      			"contains-other-v": "!${direction}",
                   ... (snipped) ...
      		},
      		{
      			"from": "p-interface",
      			"to": "vpls-pe",
      			"label": "tosca.relationships.network.BindsTo",
      			"direction": "OUT",
      			"contains-other-v": "!${direction}",
                   ... (snipped) ...
      		},
      
      		{
      			"from": "vpls-pe",
      			"to": "complex",
      			"label": "org.onap.relationships.inventory.LocatedIn",
      			"direction": "OUT",
      			"contains-other-v": "NONE",
                   ... (snipped) ...
      		},
      		{
      			"from": "vpls-pe",
      			"to": "ctag-pool",
      			"label": "org.onap.relationships.inventory.Uses",
      			"direction": "OUT",
      			"contains-other-v": "NONE",
                   ... (snipped) ...
      		},

      The generated HTML documentation for vpls-pe includes:

      Generated API HTML snippet
      GET /network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces
      GET /network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}
      PUT /network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}
      ... etc ...
      
      
      GET /network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces
      GET /network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}
      PUT /network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}
      ... etc ...
      
      PUT /network/vpls-pes/vpls-pe/{equipment-name}/relationship-list/relationship
      DELETE /network/vpls-pes/vpls-pe/{equipment-name}/relationship-list/relationship
      
      ...
      
      
      vpls-pe: object
      VPLS Provider Edge routers.
      Related Nodes
      TO complex( vpls-pe LocatedIn complex, MANY2ONE)
      TO ctag-pool( vpls-pe Uses ctag-pool, MANY2MANY)
      FROM lag-interface( lag-interface BindsTo vpls-pe, MANY2ONE)(1)
      FROM p-interface( p-interface BindsTo vpls-pe, MANY2ONE)(1)
      (1) IF this VPLS-PE node is deleted, this FROM node is DELETED also
      
      

      So the overall explanation is:

      • the EdgeRules apply to vpls-pe because it has a "relationship-list" defined in its schema
      • the EdgeRule for "lag-interface" to "vpls-pe" has "contains-other-v" with effective direction "IN", so "vpls-pe" contains an embedded "lag-interfaces" element
      • the EdgeRule for "p-interface" to "vpls-pe" has "contains-other-v" with effective direction "IN", so "vpls-pe" contains an embedded "p-interfaces" element
      • the EdgeRule for "complex" to "vpls-pe" has "contains-other-v" with effective direction "NONE", so "vpls-pe" contains "complex" data in the "relationship-list" element
      • the EdgeRule for "ctag-pool" to "vpls-pe" has "contains-other-v" with effective direction "NONE", so "vpls-pe" contains "ctag-pool" data in the "relationship-list" element
      • the generated API HTML documentation includes URLs for the "lag-interface" and "p-interface" as sub-components of the "vpls-pe" even though it appears they should be manipulated via the "relationship-list" element

      Question:

      • should the embedded "lag-interface" and "p-interface" elements really be "read-only"?
        • if so, is the generated API documentation showing redundant/deprecrated URL APIs?
      • what is the expected sequence of API calls for creating, updating and getting the "lag-interface" and "p-interface" objects from the "vpls-pe"?
      • what would happen if the "lag-interface" and "p-interface" objects are created/edited using the sub-component URLs as well as attached/detached through the "relationship-list"?
        • if both methods of manipulating the "lag-interface" and "p-interface" objects are equivalent, why is it necessary to have the "relationship-list" and EdgeRules?
        • should the embedded "lag-interface" and "p-interface" elements really be "read-only"?
          • if so, is the generated API documentation showing redundant/deprecrated URL APIs?
        • They are not read-only, all "child" objects can be updated in their own right.
        • what is the expected sequence of API calls for creating, updating and getting the "lag-interface" and "p-interface" objects from the "vpls-pe"?
        • As defined in the API documentation, you use the relevant PUT urls, specifying the UUID of the parent vpls-pe object in the URL (i.e. {equipment-name}). The payload of the PUT request will contain the child object only. You can also create child objects by performing a PUT on the parent object URL, and defining the child objects nested inside the parent object payload.
        • what would happen if the "lag-interface" and "p-interface" objects are created/edited using the sub-component URLs as well as attached/detached through the "relationship-list"?
          • if both methods of manipulating the "lag-interface" and "p-interface" objects are equivalent, why is it necessary to have the "relationship-list" and EdgeRules?
        • If the contains-other-v field in the edge rule describing the relationship between the vpls-pe and the lag-interface/p-interface is set to "IN" or "OUT", the API will only allow you to update the child object using the sub-component URL. If you attempt to use the relationship-list method to add a child, the API will return an error. The opposite will be true if the contains-other-v field is set to "NONE".
  2. I found the location of the TOSCA definition yamls in ONAP: https://gerrit.onap.org/r/gitweb?p=sdc.git;a=tree;f=common/onap-tosca-datatype/src/main/resources/globalTypes/openecomp-inventory;h=f6271b34b2d4081d0a8628544c64b449cf60d2f2;hb=refs/heads/master

    However, they do not seem to be aligned with the current contents of the OXM / dbedgerules. E.g. the relationships yaml defines relationships using the "org.openecomp" namespace, whereas the dbedgerules have been updated to use the "org.onap" namespace. We need to be careful not to let the TOSCA and the AAI schema fall too far out of sync.

    Maybe any AAI schema updates should be communicated to the SDC project PTL?

    James Forsyth Christina Monteleone

    1. If the SDC does generate OXM and EdgeRule files for AAI schema definition:

      • Does that mean we would need to deploy and run a full ONAP system with SDC before we can setup the AAI schema?
      • Does SDC have any dependencies on AAI?
      • How would we even bootstrap an ONAP system?
      1. OXM and EdgeRules are AAI's internal representation of the TOSCA schema defined by SDC, therefore SDC should not responsible for the translation of TOSCA into OXM/EdgeRules.

        I expect when the Tosca→OXM translation tool is open sourced, we would need to define a process by which the SDC TOSCA is consumed and translated to OXM/EdgeRules, which in turn is consumed by the aai-resources microservice.

        As a start, this could be a manual design-time process. I.e., when we need to make a schema change, instead of updating the OXM+EdgeRules in AAI, we update the TOSCA schema in SDC, and use the tool to generate a new version of the OXM +EdgeRules, which we then checked into the aai-schema repo.

        Eventually, the goal is to make this an dynamic process, where SDC can release a new version of the TOSCA schema at any time, and AAI will automatically consume this and update its schema at run-time.

    2. Will other components also have their XSD/HTML/YAML files generated from the TOSCA models, rather than from AAI OXM files?

      Is there/will there be a reverse-engineering tool that converts AAI OXM/EdgeRules back into TOSCA models?

      Is round-trip engineering of the AAI schema a goal of the project?

      Given the current misalignment and on-going updates to AAI schema, there will need to be tools to help SDC TOSCA models catch up.


      1. There is no such tool in the pipeline at the moment because the TOSCA is intended to be the master. As things are, I think there will be some pain at some point when we switch to using the TOSCA, to align the TOSCA with the current AAI schema.

        I don't know about how other projects will consume the TOSCA, but I do believe that there MUST be a master model referenced by the entire ONAP ecosystem, so that different components can integrate and speak the same language. Without this we will see a divergence in the modelling of various projects and components, which will lead to integration hell. Imagine trying to add a new service type that needs to be understood by multiple ONAP systems, without a common model this would be nigh on impossible.