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"
"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.NewClient("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)
Fabian Seidl
committed
request := &networkelement.GetRequest{
Timestamp: time.Now().UnixNano(),
Mneid: event.EntityID.String(),
response, err := networkElementServer.Get(ctx, request)
if err != nil {
fmt.Printf("Error %+v\n ", err)
return
}
Fabian Seidl
committed
fmt.Printf("\n[APP] Device-ID: %v, NetworkElement-Name: %+v \n", response.Mne.Id, response.Mne.Name)
Fabian Seidl
committed
d := NewDevice(uuid.MustParse(response.Mne.Id), response.Mne.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.
Fabian Seidl
committed
err = models.Unmarshal([]byte(response.Mne.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.ManagedNetworkElement{
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,
)
}
}