diff --git a/controller/controller.go b/controller/controller.go index b46d77770e7e3a94b4684e826aebebd2e300d60f..a1a24aaf60deb2c47f7b2bf4dc9aa0e37bc66fa4 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -361,6 +361,9 @@ func ensureAdminRoleExists() error { "/gosdn.topology.TopologyService/DeleteLink", "/gosdn.subscriptionmanagement.SubscriptionManagementService/ResetAllSubscriptions", "/gosdn.subscriptionmanagement.SubscriptionManagementService/GetAll", + "/gosdn.subscriptionmanagement.SubscriptionManagementService/Get", + "/gosdn.subscriptionmanagement.SubscriptionManagementService/Delete", + "/gosdn.subscriptionmanagement.SubscriptionManagementService/Add", })) if err != nil { return err diff --git a/controller/northbound/server/submanagement.go b/controller/northbound/server/submanagement.go index eb75420e7a482e753895e46d11ae687d7f10adee..8710ef3def57ebc956190fa3b8c6b6361a7dd704 100644 --- a/controller/northbound/server/submanagement.go +++ b/controller/northbound/server/submanagement.go @@ -6,6 +6,8 @@ import ( subpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/subscriptionmanagement" "code.fbi.h-da.de/danet/gosdn/controller/nucleus" + "code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi" + "github.com/google/uuid" ) // SubManagementServer represents a SubsriptionManagementServer. @@ -67,3 +69,99 @@ func (s *SubManagementServer) GetAll(ctx context.Context, request *subpb.GetAllR Subscriptions: subInfosToReturn, }, nil } + +// Get fetches detailed info for one specific available subscription. +func (s *SubManagementServer) Get(ctx context.Context, request *subpb.GetRequest) (*subpb.GetResponse, error) { + subUUID, err := uuid.Parse(request.GetSubid()) + if err != nil { + return &subpb.GetResponse{ + Timestamp: time.Now().UnixNano(), + }, err + } + + info, err := s.networkElementWatchter.GetSubscriptionInformations(subUUID) + if err != nil { + return &subpb.GetResponse{ + Timestamp: time.Now().UnixNano(), + }, err + } + + var pathsToReturn []*subpb.Path + for _, path := range info.Opts.Paths { + var elems []string + for _, elem := range path { + elems = append(elems, elem) + } + + pathsToReturn = append(pathsToReturn, &subpb.Path{Elem: elems}) + } + + return &subpb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Subscriptions: &subpb.Subscription{ + Subid: info.SubID, + Pid: info.PndID, + Mneid: info.MneID, + MneName: info.MneName, + Paths: pathsToReturn, + SubscribeOptions: &subpb.SubscribeOptions{ + GnmiMode: info.Opts.Mode, + GnmiStreamMode: info.Opts.StreamMode, + SampleInterval: info.Opts.SampleInterval, + }, + }, + }, nil +} + +// Delete stops and removes one specific running subscription is a no-op if object connected to ID does not exist. +func (s *SubManagementServer) Delete(ctx context.Context, request *subpb.DeleteRequest) (*subpb.DeleteResponse, error) { + subUUID, err := uuid.Parse(request.GetSubid()) + if err != nil { + return &subpb.DeleteResponse{ + Timestamp: time.Now().UnixNano(), + }, err + } + + s.networkElementWatchter.StopAndRemoveNetworkElementSubscription(subUUID) + + return &subpb.DeleteResponse{ + Timestamp: time.Now().UnixNano(), + }, nil +} + +// Add creates a new subscription for the network element matching the provided ID using the provided subscribe options. +func (s *SubManagementServer) Add(ctx context.Context, request *subpb.AddRequest) (*subpb.AddResponse, error) { + mneID, err := uuid.Parse(request.GetMneid()) + if err != nil { + return &subpb.AddResponse{ + Timestamp: time.Now().UnixNano(), + }, err + } + + var paths [][]string + for _, path := range request.Subscription.Paths { + var elems []string + for _, elem := range path.Elem { + elems = append(elems, elem) + } + paths = append(paths, elems) + } + + err = s.networkElementWatchter.SubscribeToNetworkElementWithID(mneID, + &gnmi.SubscribeOptions{ + Mode: request.Subscription.SubscribeOptions.GnmiMode, + StreamMode: request.Subscription.SubscribeOptions.GnmiStreamMode, + SampleInterval: request.Subscription.SubscribeOptions.SampleInterval, + Paths: paths, + }, + ) + if err != nil { + return &subpb.AddResponse{ + Timestamp: time.Now().UnixNano(), + }, err + } + + return &subpb.AddResponse{ + Timestamp: time.Now().UnixNano(), + }, nil +} diff --git a/controller/nucleus/networkElementWatcher.go b/controller/nucleus/networkElementWatcher.go index dd8713aa834ce8156ce423f98a7a9e40e328fb8e..e6d19efd4019d24a953db1745ab46a65e4562769 100644 --- a/controller/nucleus/networkElementWatcher.go +++ b/controller/nucleus/networkElementWatcher.go @@ -14,6 +14,7 @@ import ( "code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement" "code.fbi.h-da.de/danet/gosdn/controller/interfaces/transport" "code.fbi.h-da.de/danet/gosdn/controller/nucleus/types" + "code.fbi.h-da.de/danet/gosdn/controller/store" "code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi" "github.com/google/uuid" gpb "github.com/openconfig/gnmi/proto/gnmi" @@ -104,6 +105,19 @@ func (n *NetworkElementWatcher) SubscribeToNetworkElement(mne networkelement.Net n.subscribeToNetworkElement(mne, opts) } +// SubscribeToNetworkElementWithID subscribes to the network element matching the provided ID according to provided SubscribeOptions. +// SubscribeOptions can be nil. Use nil for a fixed, pre-defined set of gNMI subscription options (streaming in sample mode each second). +func (n *NetworkElementWatcher) SubscribeToNetworkElementWithID(mneID uuid.UUID, opts *gnmi.SubscribeOptions) error { + mne, err := n.mneService.Get(store.Query{ID: mneID}) + if err != nil { + log.Error(err) + return err + } + + n.subscribeToNetworkElement(mne, opts) + return nil +} + func (n *NetworkElementWatcher) subscribeToNetworkElement(mne networkelement.NetworkElement, opts *gnmi.SubscribeOptions) { subID := uuid.New()