Newer
Older
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/google/uuid"
"github.com/openconfig/ygot/ygot"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"code.fbi.h-da.de/danet/gosdn/application-framework/event"
"code.fbi.h-da.de/danet/gosdn/application-framework/models"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
// Application is an example for a sdn application.
type Application struct {
eventService event.ServiceInterface
stopChannel chan os.Signal
grpcClientConn *grpc.ClientConn
}
// Run runs the application.
func (a *Application) Run() {
signal.Notify(a.stopChannel, os.Interrupt, syscall.SIGTERM)
a.eventService.SubscribeToEventType([]event.TypeToCallbackTuple{
{Type: event.Update, Callback: a.callback},
})
a.eventService.SetupEventReciever(a.stopChannel)
conn, err := grpc.Dial("localhost:55055", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
a.grpcClientConn = conn
var forever chan struct{}
go func() {
for {
select {
case <-a.stopChannel:
close(forever)
_ = a.grpcClientConn.Close()
return
}
}
}()
<-forever
}
func (a *Application) callback(event *event.Event) {
ctx := context.Background()
networkElementServer := networkelement.NewNetworkElementServiceClient(a.grpcClientConn)
request := &networkelement.GetNetworkElementRequest{
Timestamp: time.Now().UnixNano(),
NetworkElementId: event.EntityID.String(),
response, err := networkElementServer.Get(ctx, request)
if err != nil {
fmt.Printf("Error %+v\n ", err)
return
}
fmt.Printf("\n[APP] Device-ID: %v, NetworkElement-Name: %+v \n", response.NetworkElement.Id, response.NetworkElement.Name)
d := NewDevice(uuid.MustParse(response.NetworkElement.Id), response.NetworkElement.Name)
// Create 'root' path to be able to load the whole model from the store.
path, err := ygot.StringToPath("/", ygot.StructuredPath)
if err != nil {
panic(err)
}
// Use unmarshall from the devices SBI to unmarshall ygot json in go struct.
err = models.Unmarshal([]byte(response.NetworkElement.Model), path, &d.Model)
if err != nil {
panic(err)
}
if *d.Model.System.Config.Hostname != d.Name {
fmt.Printf("[APP] Device.Name (%s) doesn't match Device.Hostname (%s) in model! Updating...\n",
d.Name,
*d.Model.System.Config.Hostname,
)
*d.Model.System.Config.Hostname = d.Name
modelAsString, err := models.GetModelAsString(&d.Model)
if err != nil {
panic(err)
}
requestUpdate := &networkelement.UpdateNetworkElementRequest{
Timestamp: time.Now().UnixNano(),
NetworkElement: &networkelement.NetworkElement{
Id: d.UUID.String(),
Name: d.Name,
Model: modelAsString,
},
}
updateResponse, err := networkElementServer.Update(ctx, requestUpdate)
if err != nil {
panic(err)
}
fmt.Printf("[APP] Update response: %+v", updateResponse)
} else {
fmt.Printf("[APP] Device.Name (%s) does match Device.Hostname (%s) in model! Nothing to do for me...\n",
d.Name,
*d.Model.System.Config.Hostname,
)
}
}