Newer
Older
Andre Sterba
committed
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
Andre Sterba
committed
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology"
"code.fbi.h-da.de/danet/gosdn/application-framework/event"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
// Application is an example for a sdn application.
type Application struct {
eventServiceLinks event.ServiceInterface
eventServiceRoutes event.ServiceInterface
stopChannel chan os.Signal
grpcClientConn *grpc.ClientConn
}
// Run runs the application.
func (a *Application) Run(controllerAddress string) {
signal.Notify(a.stopChannel, os.Interrupt, syscall.SIGTERM)
a.eventServiceLinks.SubscribeToEventType([]event.TypeToCallbackTuple{
{Type: event.Add, Callback: a.LinksCallback},
{Type: event.Update, Callback: a.LinksCallback},
})
a.eventServiceLinks.SetupEventReciever(a.stopChannel)
a.eventServiceRoutes.SubscribeToEventType([]event.TypeToCallbackTuple{
{Type: event.Add, Callback: a.RoutesCallback},
{Type: event.Update, Callback: a.RoutesCallback},
})
a.eventServiceRoutes.SetupEventReciever(a.stopChannel)
conn, err := grpc.NewClient(controllerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
Andre Sterba
committed
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
}
// LinksCallback is the callback function for link changes.
func (a *Application) LinksCallback(event *event.Event) {
fmt.Printf("Links Event Callback: %+v \n", event)
ctx := context.Background()
networkElementServer := networkelement.NewNetworkElementServiceClient(a.grpcClientConn)
Andre Sterba
committed
topologyServer := topology.NewTopologyServiceClient(a.grpcClientConn)
getTopologyRequest := &topology.GetTopologyRequest{
Timestamp: time.Now().UnixNano(),
}
getTopologyResponse, err := topologyServer.GetTopology(ctx, getTopologyRequest)
if err != nil {
fmt.Printf("Error %+v\n ", err)
return
}
links := getTopologyResponse.Toplogy.Links
for _, link := range links {
fmt.Printf("[APP] Link: %+v", link)
adjustNodePortsToMatchConfiguration(networkElementServer, link.SourceNode, link.SourcePort)
adjustNodePortsToMatchConfiguration(networkElementServer, link.TargetNode, link.TargetPort)
Andre Sterba
committed
}
}
// RoutesCallback is the callback function for route changes.
func (a *Application) RoutesCallback(event *event.Event) {
fmt.Printf("Routes Event Callback: %+v \n", event)
ctx := context.Background()
networkElementServer := networkelement.NewNetworkElementServiceClient(a.grpcClientConn)
Andre Sterba
committed
routesServer := topology.NewRoutingTableServiceClient(a.grpcClientConn)
getRoutingTablesRequest := &topology.GetRoutesRequest{
Timestamp: time.Now().UnixNano(),
}
response, err := routesServer.GetRoutes(ctx, getRoutingTablesRequest)
if err != nil {
fmt.Printf("Error %+v\n ", err)
return
}
for _, node := range response.RoutingTables {
nodeID := node.NodeID
for _, nodeRoute := range node.Routes {
adjustNodeRoutesToMatchConfiguration(networkElementServer, nodeID, nodeRoute)