Skip to content
Snippets Groups Projects
client.go 3.03 KiB
Newer Older
  • Learn to ignore specific revisions
  • package database
    
    import (
    
    	"code.fbi.h-da.de/cocsn/yang-modules/generated/tapi"
    
    	"github.com/neo4j/neo4j-go-driver/neo4j"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	log "github.com/sirupsen/logrus"
    
    //Client is a database client
    
    type Client struct {
    	driver     neo4j.Driver
    	tapiClient *tapiDatabaseClient
    
    //NewDatabaseClient creates a database client
    
    func NewDatabaseClient(uri, username, password string,
    	encrypted bool) (*Client, error) {
    
    	d, err := createDriver(uri, username, password, encrypted)
    
    	if err != nil {
    		return nil, err
    
    
    	return &Client{
    		driver:     d,
    		tapiClient: newTapiDatabaseClient(d),
    	}, nil
    
    }
    
    //createDriver creates a neo4j.Driver instance
    
    func createDriver(uri, username, password string, encrypted bool) (neo4j.Driver, error) {
    	return neo4j.NewDriver(
    
    		uri,
    		neo4j.BasicAuth(username, password, ""),
    		func(c *neo4j.Config) {
    			c.Encrypted = encrypted
    		},
    	)
    }
    
    
    //PND is a principle network domain
    type PND struct {
    	Name        string
    	Description string
    	Interfaces  []string
    
    //storePndTxFunc transaction to store a pnd in the database
    func storePndTxFunc(name, description string, interfaces []string) neo4j.TransactionWork {
    	return func(tx neo4j.Transaction) (interface{}, error) {
    		query :=
    			`
    			MERGE (pnd:PND {name: $name})
    			ON CREATE SET pnd.description = $description,
    				pnd.interfaces = $interfaces
    			RETURN pnd
    			`
    
    		result, err := tx.Run(query, map[string]interface{}{
    			"name":        name,
    			"description": description,
    			"interfaces":  interfaces,
    		})
    
    		if err != nil {
    
    Malte Bauch's avatar
    Malte Bauch committed
    			//TODO: handle neo4j.isServiceUnavailable()
    
    			return nil, err
    		}
    
    		if result.Next() {
    			return result.Record().GetByIndex(0), nil
    		}
    
    		return nil, errors.New("expected a record")
    	}
    }
    
    
    //StorePND stores the given principle network domain
    
    func (c Client) StorePND(pnd *PND) neo4j.Node {
    	session := createSession(c.driver, true)
    
    Malte Bauch's avatar
    Malte Bauch committed
    	defer session.Close()
    
    
    	result, err := session.WriteTransaction(storePndTxFunc(pnd.Name, pnd.Description, pnd.Interfaces))
    
    	if err != nil {
    
    		log.Info(err)
    
    	log.Info("created/updated PND with id: ", result.(neo4j.Node).Id())
    
    	return result.(neo4j.Node)
    
    //StoreDevice stores a network device into the neo4j database as a node
    func (c Client) StoreDevice(device interface{}, pndID int64) ([]neo4j.Node, error) {
    
    	switch device := device.(type) {
    	case *tapi.TapiCommon_Context_TopologyContext_Topology_Node:
    
    		return c.tapiClient.storeNode(*device.Uuid, *device.Name["nativeName"].Value, pndID)
    
    	default:
    		return nil, errors.New("unsupported DeviceType")
    	}
    }
    
    //StoreLink stores a link between network devices into the neo4j database as a
    //relationship
    func (c Client) StoreLink(device interface{}) ([]neo4j.Relationship, error) {
    	switch device := device.(type) {
    	case *tapi.TapiCommon_Context_TopologyContext_Topology_Link:
    		var nep1 string
    		var nep2 string
    
    		count := 0
    		for _, nep := range device.NodeEdgePoint {
    			if count == 0 {
    				nep1 = *nep.NodeUuid
    			} else {
    				nep2 = *nep.NodeUuid
    			}
    			count++
    		}
    		return c.tapiClient.storeLink(nep1, nep2)
    
    	default:
    		return nil, errors.New("unsupported DeviceType")
    
    Malte Bauch's avatar
    Malte Bauch committed
    	}