Package com.tailf.navu

NAVU (Navigation Utilities) is an API which provides increased accessibility to the ConfD/NCS populated data model tree: NAVU-Tree.

See: Description

Package com.tailf.navu Description

NAVU (Navigation Utilities) is an API which provides increased accessibility to the ConfD/NCS populated data model tree: NAVU-Tree.

It is important to understand the distinction between a populated data tree and a schema tree.

The NAVU-Tree is build on top of the schema tree MaapiSchemas which is a linked structures of MaapiSchemas.CSNode nodes. Each node in NAVU holds a reference to CSNode representation and could be obtained through NavuNodeInfo.getCSNode():

   NavuNode node = ...;
   MaapiSchemas.CSNode rawCSNode = node.getInfo().getCSNode();
 

Navigation is done entirely on the populated NAVU-Tree. Each keypath represents a node or a NavuNode.

A context (NavuContext) needs to be created and supplied before further navigation can be performed.

   NavuContext context = new NavuContext(maapi);
   context.startRunningTrans(Conf.MODE_READ_WRITE);
   NavuContainer base = new NavuContainer(context);
 
NAVU uses its current context to retrieve its list instances with keys and its leafs with data values.

In NAVU a list instance is mapping between a ConfKey and a instance of NavuListEntry which is a subclass of NavuContainer. the NavuList.elem(String) locates the list entry.

A NavuLeaf holds a value (ConfValue) that is retrieved through the current NavuContext. A list instance is NAVU caches data through its NAVU-Tree.

NAVU builds up its tree in lazily fashion, which means that it populates its children in one level at the time. Internal in each NAVU class there exists a refresh method that retrieves the children nodes and stores them in a hash map.

A explicit instance of a NavuContainer with only the NavuContext:

    NavuContext context = new NavuContext(maapi);
    context.startRunningTrans(Conf.MODE_READ_WRITE);
    NavuContainer base = new NavuContainer(context);
    assert base.getInfo().isRootOfModules();
 
Is the base of the NAVU-Tree. The base of the NAVU-Tree represents only a "dummy" base node. Operation on this node will throw exceptions.

The only operation that should be done on the base node is to explicitly call NavuNode.container(Integer) with the module hash as its argument.

       ConfNamespace ns = new MyNamespace();
       final int hash = ns.hash();
       NavuContainer module = base.container(hash);
 

The module reference in the above snippet represents the node that "points" to the module of a specific yang module.

When we reach the point where we have a reference to a specific module the next step would be to call: NavuNode.container(String), NavuNode.list(String) or NavuNode.leaf(String) to move to the next level (depending on how the yang module is modeled).

The main features of the NAVU are:

The key component of the NAVU is the MAAPI schema functionality. The schema provides schema knowledge of the YANG model on which the data model. The navigation is done in runtime according to the schema loaded at creation time of the root node.

One of the ideas behind NAVU is that it shall be easy to use for people that have a good understanding of the yang modeling language. Hence, primitives and classes are named according to the yang modeling building blocks. The "navigation" is performed by navigating top down from the root module down through the model. This done using the primitives container, list, leaf and elem.

The following nodes types are provided by the NAVU.

NAVU becomes aware of the schema at start up time. Hence, any schema violating operations will be detected at runtime. Furthermore, NAVU only reads data when it is needed. So even if you have a very large tree structure, NAVU will only attempt read data when the data is required.

It is not a prerequisite, but it is highly recommended to use confdc/ncsc to generate namespace classes. By using confdc generated. namespace classes you get the following benefits:

The following example shows yang model used in the examples.

  module navutest {
    namespace "http://examples.com/navutest";
    prefix nt;

    import tailf-common {
      prefix tailf;
    }

    container address-book {
      list friends {
        key "name";
        leaf name {
          type string;
        }

        leaf age {
          type uint8;
        }

        tailf:action friday-night-call {
          tailf:actionpoint friendly-action;
          input {
            leaf request {
              type string;
            }
          }
          output {
            leaf response {
              type string;
            }
          }
        }
      }
    }
  }
 
Example 1: Iterating through a list.
 navutest ntns = new navutest();
 NavuContext context = new NavuContext(maapi);
 context.startRunningTrans(Conf.MODE_READ_WRITE);
 NavuContainer base = new NavuContainer(context);
 NavuContainer nt = base.container(ntns.hash());

 NavuList friends = nt.container(ntns.nt_address_book_).
                         list(ntns.nt_friends_);

 for (NavuContainer friend: friends.elements()) {
     System.out.println(friend.leaf(ntns.nt_age_).value());
 }
 
Example 2: Executing an action.
 NavuContext context = new NavuContext(maapi);
 context.startRunningTrans(Conf.MODE_READ_WRITE);
 NavuContainer base = new NavuContainer(context);
 NavuContainer nt = base.container(ntns.hash());

 friends =  nt.container(ntns.nt_address_book_).
                list(ntns.nt_friends_);

 for (NavuContainer friend: friends.elements()) {
     NavuAction action =
               friend.action("friday-night-call");
     ConfXMLParam[] result =
               action.call(new ConfXMLParam[]{
                           new ConfXMLParamValue(ntns.hash(),
                                     ntns.nt_request,
                                     new ConfBuf("the string"))
               });
     result = action.call("the string");
 }
 
Example 3: Using regexp search.

This example shows how to use a regular expression when navigating NAVU. The expression is divided by "/" per level. Furthermore, a list element have two levels; one for the list node name, and one for the list element key.

 NavuContext context = new NavuContext(maapi);
 context.startRunningTrans(Conf.MODE_READ_WRITE);
 NavuContainer base = new NavuContainer(context);
 NavuContainer nt = base.container(ntns.hash());
 Collection friendsColl =  nt.select(".*/.*/.*");

 for (NavuNode friend: friendsColl) {
     System.out.println(
         ((NavuContainer)friend).leaf(ntns.nt_name_).value());
     System.out.println(
         ((NavuContainer)friend).leaf(ntns.nt_age_).value());
  }
 
Example 4: Using XPath search.
 NavuContext context = new NavuContext(maapi);
 context.startRunningTrans(Conf.MODE_READ_WRITE);
 NavuContainer base = new NavuContainer(context);
 NavuContainer nt = base.container(ntns.hash());
 Collection friendsUno =
     nt.container(ntns.nt_address_book).
         xPathSelect("friends[name='uno']/*");

 for (NavuNode friend: friendsUno) {
     System.out.println(((NavuLeaf)friend).value());
 }