Skip to content
Snippets Groups Projects
Commit 25eab34c authored by Malte Bauch's avatar Malte Bauch
Browse files

refactoring database to use transactions

changed StoreNodes(), StoreLinks(), StorePND() to return the created nodes/relationships aswell
parent 114c6d21
No related branches found
No related tags found
2 merge requests!43Resolve "neo4j",!18Develop
Pipeline #52510 passed with warnings
......@@ -2,6 +2,7 @@ package database
import (
"code.fbi.h-da.de/cocsn/gosdn/log"
"errors"
"github.com/neo4j/neo4j-go-driver/neo4j"
)
......@@ -12,9 +13,9 @@ type Database struct {
//PND is a principle network domain
type PND struct {
name string
description string
southboundInterfaces []string
name string
description string
interfaces []string
}
//NewDatabaseClient creates a database client
......@@ -57,36 +58,53 @@ func createSession(driver neo4j.Driver, write bool) neo4j.Session {
session, err := driver.NewSession(sessionConfig)
if err != nil {
log.Info("failed creating database session:", err)
log.Info(err)
}
return session
}
//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 {
return nil, err
}
if result.Next() {
log.Info(result.Consume())
return result.Record().GetByIndex(0), nil
}
return nil, errors.New("expected a record")
}
}
//StorePND stores the given principle network domain
func (d Database) StorePND(pnd *PND) {
func (d Database) StorePND(pnd *PND) neo4j.Node {
session := createSession(d.driver, true)
defer session.Close()
query :=
`
MERGE (pnd:PND {name: $name})
ON CREATE SET pnd.description = $description,
pnd.southboundInterfaces = $southboundInterfaces
`
//refactor map[string]interface... in own function
_, err := session.Run(
query, map[string]interface{}{
"name": pnd.name,
"description": pnd.description,
"southboundInterfaces": pnd.southboundInterfaces,
})
result, err := session.WriteTransaction(storePndTxFunc(pnd.name, pnd.description, pnd.interfaces))
if err != nil {
log.Info("failed storing PND into database:", err)
log.Info(err)
}
log.Info("successfully added PND into database")
return result.(neo4j.Node)
}
//RemovePND removes the given principle network domain by id.
......@@ -98,44 +116,65 @@ func (d Database) GetNodesByLabel(label string) {}
func (d Database) GetDeviceByID(id string) {}
func storeNodesTxFunc(json string, id int64) neo4j.TransactionWork {
return func(tx neo4j.Transaction) (interface{}, error) {
var nodelist []neo4j.Node
query :=
`
WITH apoc.convert.fromJsonMap($stringToAdd)
AS value
UNWIND value.data as d
MERGE (device:Device {id: d.object_id})
ON CREATE SET device.nativeName = d.object_data.` + "`tapi-object-data`.name[0].value," + `
device.deviceType = d.object_data.` + "`tapi-object-data`.name[1].value," + `
device.serialNumber = d.object_data.` + "`tapi-object-data`.name[2].value," + `
device.softwareVersion = d.object_data.` + "`tapi-object-data`.name[3].value," + `
device.` + "`operational-state` = d.object_data.`tapi-object-data`.`operational-state`" + `
WITH device
MATCH (pnd:PND)
WHERE id(pnd) = $pnd
MERGE (device)-[:BELONGS_TO]->(pnd)
RETURN device
`
result, err := tx.Run(query, map[string]interface{}{
"stringToAdd": json,
"pnd": id,
})
if err != nil {
return nil, err
}
for result.Next() {
nodelist = append(nodelist, result.Record().GetByIndex(0).(neo4j.Node))
}
if err = result.Err(); err != nil {
return nil, err
}
return nodelist, nil
}
}
//StoreNodes stores the given nodes to the database and adds them to a
//principle networt domain (PND). It is required for a node to belong to a PND.
func (d Database) StoreNodes(json string) {
func (d Database) StoreNodes(json string) []neo4j.Node {
//TODO: remove this after testing and add own gRPC call for it
testPND := PND{name: "test_PND", description: "very, interesting", southboundInterfaces: []string{"TAPI", "RESTCONF"}}
d.StorePND(&testPND)
testPND := PND{name: "test_PND", description: "very interesting", interfaces: []string{"TAPI", "RESTCONF"}}
pnd := d.StorePND(&testPND).Id()
log.Info(pnd)
session := createSession(d.driver, true)
defer session.Close()
query :=
`
WITH apoc.convert.fromJsonMap($stringToAdd)
AS value
UNWIND value.data as d
MERGE (device:Device {id: d.object_id})
ON CREATE SET device.nativeName = d.object_data.` + "`tapi-object-data`.name[0].value," + `
device.deviceType = d.object_data.` + "`tapi-object-data`.name[1].value," + `
device.serialNumber = d.object_data.` + "`tapi-object-data`.name[2].value," + `
device.softwareVersion = d.object_data.` + "`tapi-object-data`.name[3].value," + `
device.` + "`operational-state` = d.object_data.`tapi-object-data`.`operational-state`" + `
WITH device
MATCH (pnd:PND)
WHERE pnd.name = $pnd
MERGE (device)-[:BELONGS_TO]->(pnd)
`
_, err := session.Run(
query, map[string]interface{}{
"stringToAdd": json,
"pnd": testPND.name,
})
result, err := session.WriteTransaction(storeNodesTxFunc(json, pnd))
if err != nil {
log.Info("failed storing Nodes into database:", err)
log.Info(err)
}
log.Info("successfully added Nodes into database")
return result.([]neo4j.Node)
}
//RemoveNodes removes the given nodes and their relationships
......@@ -144,33 +183,53 @@ func (d Database) RemoveNodes(json string) {}
//RemoveSingleNode removes the given node and their relationship by id.
func (d Database) RemoveSingleNode(id string) {}
func storeLinksTxFunc(json string) neo4j.TransactionWork {
return func(tx neo4j.Transaction) (interface{}, error) {
var relationsList []neo4j.Relationship
query :=
`
WITH apoc.convert.fromJsonMap($stringToAdd)
AS value
UNWIND value.data as l
MATCH (d:Device), (d2:Device)
WHERE d.id = l.object_data.` + "`tapi-object-data`.`node-edge-point`[0].`node-uuid`" + `
AND d2.id = l.object_data.` + "`tapi-object-data`.`node-edge-point`[1].`node-uuid`" + `
CALL apoc.merge.relationship(d,l.object_data.` + "`tapi-object-data`.`layer-qualifier`,{},{}, d2,{})" + `
YIELD rel
RETURN rel
`
result, err := tx.Run(query, map[string]interface{}{
"stringToAdd": json,
})
if err != nil {
return nil, err
}
for result.Next() {
relationsList = append(relationsList, result.Record().GetByIndex(0).(neo4j.Relationship))
}
if err = result.Err(); err != nil {
return nil, err
}
return relationsList, nil
}
}
//StoreLinks stores the links between nodes
func (d Database) StoreLinks(json string) {
func (d Database) StoreLinks(json string) []neo4j.Relationship {
session := createSession(d.driver, true)
defer session.Close()
query :=
` WITH apoc.convert.fromJsonMap($stringToAdd)
AS value
UNWIND value.data as l
MATCH (d:Device), (d2:Device)
WHERE d.id = l.object_data.` + "`tapi-object-data`.`node-edge-point`[0].`node-uuid`" + `
AND d2.id = l.object_data.` + "`tapi-object-data`.`node-edge-point`[1].`node-uuid`" + `
CALL apoc.merge.relationship(d,l.object_data.` + "`tapi-object-data`.`layer-qualifier`,{},{}, d2,{})" + `
YIELD rel
RETURN rel
`
_, err := session.Run(
query, map[string]interface{}{
"stringToAdd": json,
})
result, err := session.WriteTransaction(storeLinksTxFunc(json))
if err != nil {
log.Info("failed storing Links into database:", err)
log.Info(err)
}
log.Info("successfully added Links into database")
return result.([]neo4j.Relationship)
}
//StoreNodeEdgePoints stores the given node edge points (interfaces)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment