Skip to content
Snippets Groups Projects
app.go 3 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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)
    
    	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
    	}
    
    
    	fmt.Printf("\n[APP] Device-ID: %v, NetworkElement-Name: %+v \n", response.Mne.Id, response.Mne.Name)
    
    	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.
    
    	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,
    		)
    	}
    }