API Examples for Golang

The following are a few examples on how to use the Golang API generated from the onos-topo gRPC API.

All the examples assume that the following import is available:

import "github.com/onosproject/onos-api/go/topo"

Similarly, all examples assume that the TopoService client has been obtained and that context ctx was either provided or created via code similar to the following:

client := topo.CreateTopoClient(conn)
...
ctx := context.Background()

Create an Entity

The following example shows how to create an Entity of e2cell kind, with a couple of separate aspects of information - Location, Coverage and E2Cell:

cell := &topo.Object{
    ID:   topo.ID(cellID),
    Type: topo.Object_ENTITY,
    Obj: &topo.Object_Entity{
        Entity: &topo.Entity{
            KindID: topo.ID(topo.E2CELL),
        },
    }
}
cell.SetAspect(&topo.Location{Lat: 50.08834, Lng: 14.40372})
cell.SetAspect(&topo.Coverage{Height: 8.7, ArcWidth: 120.0, Azimuth: 315.0, Tilt: -5.0})
cell.SetAspect(&topo.E2Cell{CellObjectID: "4269A20", AntennaCount: 5, EARFCN: 69, PCI: 42, CellType: "FEMTO"})

resp, err := client.Create(ctx, &topo.CreateRequest{Object: cell})

Create a Relation

Here we can see an example of creating Relation of neighbors kind, representing one cell being a neighbor of another. There are no aspects annotating this relation. Also, note that if the relation ID is unspecified during the creation, one will be automatically generated using the topo.RelationID(...) method, based on the source, kind and the target IDs.

relation := &topo.Object{
    Type: topo.Object_RELATION,
    Obj: &topo.Object_Relation{
        Entity: &topo.Relation{
            KindID: topo.ID(topo.NEIGHBORS),
            SrcEntityID: cellID,
            TgtEntityID: neighborCellID,
        },
    }
}

resp, err := client.Create(ctx, &topo.CreateRequest{Object: relation})

Get an Object

In order to retrieve a specific object, one must simply provide its ID. To access a specific aspect, create an instance of the aspect object and pass its reference to the GetAspect method of the topology object:

cell, err := client.Get(ctx, &topo.GetRequest{ID: cellID})
if err == nil { ... }
coverage := &topo.Coverage{}
cell.GetAspect(coverage)

Update an Entity

To update an aspect of an object, one must first obtain the object via Get, update its structure and then call the Update method:

cell, err := client.Get(&topo.GetRequest{ID: cellID})
if err == nil { ... }
cell.SetAspect(&topo.Location{Lat: 50.08834, Lng: 14.40372})

resp, err := client.Update(ctx, &topo.UpdateRequest{Object: cell})

List Objects

The List method can be used to obtain various collections of objects using Filters specified as part of the request. Presently, there are several types of filters.

  • Object Type filter - specifies which types of objects are relevant

  • Entity or Relation Kind filter - specifies which kinds of entities or relations are relevant

  • Label filters - specifies criteria to filter on specific labels and their values

  • Relation filter - allows finding objects related to another object via a particular kind of relation

The object kind and label filters can specify values via equal, in and not operators.

Furthermore, the results can be optionally sorted (ascending or descending) by the ID of the objects. This can be useful for applications where determinism in the returned results is desirable.

Here is an example of requesting only Entity objects, of either e2node or e2cell kind, sorted in the ascending order of their IDs:

filters := &topo.Filters{
	KindFilter: &topoapi.Filter{
        Filter: &topoapi.Filter_In{In: &topoapi.InFilter{Values: []string{topo.E2NODE, topo.E2CELL}}},
    },
}
resp, err := client.List(ctx, &topo.ListRequest{Filters: filters, SortOrder: topo.SortOrder_ASCENDING})

The following shows how to obtain an unordered list of e2cell entities, related to a specified node entity using a contains relation:

resp, err := client.List(ctx, &topo.ListRequest{Filters: &topo.Filters{
                RelationFilter: &topo.RelationFilter{
                    SrcId:        nodeID,
                    RelationKind: topo.CONTAINS,
                    TargetKind:   topo.E2CELL,
                },
            }})

Watch Changes

The topology API allows clients to watch the changes in real-time via its Watch method which delivers its results as a continuous stream of events. These include not only the usual create, update, and delete events, but also replay events to indicate the object as it existed prior to the Watch being called.

As with the List method, the results can be further narrowed by specifying Filters in the request. Here is a simple example of the Watch usage, which does not specify any filters:

stream, err := client.Watch(ctx, &topo.WatchRequest{})
if err == nil { ... }

for {
    msg, err := stream.Recv()
    if err == io.EOF {
        break
    }
    if err != nil { ... }
    processEvent(msg.Event.Type, msg.Event.Object)
}

The client can cancel the watch at anytime by invoking ctx.Done().

Delete an Object

Deleting an object requires to merely provide its ID:

node, err := client.Delete(ctx, &topo.DeleteRequest{ID: nodeID})
if err == nil { ... }