Multiple E2T instance feature - Introduced APIs Delete E2T Instance and associate... 94/2094/3
authorprabhukaliswamy <prabhu.k@nokia.com>
Mon, 23 Dec 2019 09:51:01 +0000 (09:51 +0000)
committerPrabhu K <prabhu.k@nokia.com>
Wed, 25 Dec 2019 16:29:15 +0000 (16:29 +0000)
Change-Id: Ic3380caee22e53daf46ffc8a26a828003d218f3b
Signed-off-by: prabhukaliswamy <prabhu.k@nokia.com>
14 files changed:
Dockerfile
RELNOTES
cmd/rtmgr.go
container-tag.yaml
pkg/nbi/httpgetter.go
pkg/nbi/httprestful.go
pkg/nbi/httprestful_test.go
pkg/nbi/types.go
pkg/rpe/rmr.go
pkg/rpe/rmr_test.go
pkg/rpe/rpe.go
pkg/rpe/types.go
pkg/sdl/file.go
pkg/sdl/types.go

index e69fc75..faec945 100644 (file)
@@ -23,7 +23,7 @@
 # a Docker tag from the string in file container-tag.yaml
 
 #FROM golang:1.12.1 as rtmgrbuild
-FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:2-u18.04-nng as rtmgrbuild
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:3-u18.04-nng as rtmgrbuild
 
 # Install RMr shared library
 RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.10.2_amd64.deb/download.deb && dpkg -i rmr_1.10.2_amd64.deb && rm -rf rmr_1.10.2_amd64.deb
index 20b981c..f7946db 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,3 +1,6 @@
+### v0.4.5
+* Multiple E2T instance Feature: Introduced APIs Delete E2T Instance, associate RANs to E2T and disassociate RANs from E2T Instance.
+
 ### v0.4.4
 * Create E2T Instance API introduced for Multiple E2T Feature
 
index a33437a..ceb28e8 100644 (file)
@@ -45,6 +45,7 @@ import (
        "routing-manager/pkg/sdl"
        "syscall"
        "time"
+       "sync"
 )
 
 const SERVICENAME = "rtmgr"
@@ -63,16 +64,18 @@ func initRtmgr() (nbiEngine nbi.Engine, sbiEngine sbi.Engine, sdlEngine sdl.Engi
        return nil, nil, nil, nil, err
 }
 
-func serveSBI(triggerSBI <-chan bool, sbiEngine sbi.Engine, sdlEngine sdl.Engine, rpeEngine rpe.Engine) {
+func serveSBI(triggerSBI <-chan bool, sbiEngine sbi.Engine, sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) {
        for {
                if <-triggerSBI {
+                       m.Lock()
                        data, err := sdlEngine.ReadAll(xapp.Config.GetString("rtfile"))
+                       m.Unlock()
                        if err != nil || data == nil {
                                xapp.Logger.Error("Cannot get data from sdl interface due to: " + err.Error())
                                continue
                        }
                        sbiEngine.UpdateEndpoints(data)
-                       policies := rpeEngine.GeneratePolicies(rtmgr.Eps)
+                       policies := rpeEngine.GeneratePolicies(rtmgr.Eps, data)
                        err = sbiEngine.DistributeAll(policies)
                        if err != nil {
                                xapp.Logger.Error("Routing table cannot be published due to: " + err.Error())
@@ -81,12 +84,12 @@ func serveSBI(triggerSBI <-chan bool, sbiEngine sbi.Engine, sdlEngine sdl.Engine
        }
 }
 
-func serve(nbiEngine nbi.Engine, sbiEngine sbi.Engine, sdlEngine sdl.Engine, rpeEngine rpe.Engine) {
+func serve(nbiEngine nbi.Engine, sbiEngine sbi.Engine, sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) {
 
        triggerSBI := make(chan bool)
 
        nbiErr := nbiEngine.Initialize(xapp.Config.GetString("xmurl"), xapp.Config.GetString("nbiurl"), xapp.Config.GetString("rtfile"), xapp.Config.GetString("cfgfile"),
-               sdlEngine, rpeEngine, triggerSBI)
+               sdlEngine, rpeEngine, triggerSBI, m)
        if nbiErr != nil {
                xapp.Logger.Error("Failed to initialize nbi due to: " + nbiErr.Error())
                return
@@ -101,7 +104,7 @@ func serve(nbiEngine nbi.Engine, sbiEngine sbi.Engine, sdlEngine sdl.Engine, rpe
        defer sbiEngine.Terminate()
 
        // This SBI Go routine is trtiggered by periodic main loop and when data is recieved on REST interface.
-       go serveSBI(triggerSBI, sbiEngine, sdlEngine, rpeEngine)
+       go serveSBI(triggerSBI, sbiEngine, sdlEngine, rpeEngine, m)
 
        for {
                if xapp.Config.GetString("nbi") == "httpGetter" {
@@ -139,6 +142,9 @@ func main() {
        SetupCloseHandler()
        xapp.Logger.Info("Start " + SERVICENAME + " service")
        rtmgr.Eps = make(rtmgr.Endpoints)
-       serve(nbiEngine, sbiEngine, sdlEngine, rpeEngine)
+
+       var m sync.Mutex
+
+       serve(nbiEngine, sbiEngine, sdlEngine, rpeEngine, &m)
        os.Exit(0)
 }
index cfdbfb8..a89789a 100644 (file)
@@ -2,4 +2,4 @@
 # By default this file is in the docker build directory,
 # but the location can configured in the JJB template.
 ---
-tag: 0.4.4
+tag: 0.4.5
index fca48f4..5d7b818 100644 (file)
@@ -38,6 +38,7 @@ import (
        "routing-manager/pkg/rtmgr"
        "routing-manager/pkg/sdl"
        "time"
+       "sync"
 )
 
 type HttpGetter struct {
@@ -77,7 +78,7 @@ func fetchAllXApps(xmurl string) (*[]rtmgr.XApp, error) {
 }
 
 func (g *HttpGetter) Initialize(xmurl string, nbiif string, fileName string, configfile string,
-       sdlEngine sdl.Engine, rpeEngine rpe.Engine, triggerSBI chan<- bool) error {
+       sdlEngine sdl.Engine, rpeEngine rpe.Engine, triggerSBI chan<- bool, m *sync.Mutex) error {
        return nil
 }
 
index 5e90bfa..2e14690 100644 (file)
@@ -49,6 +49,8 @@ import (
        "routing-manager/pkg/sdl"
        "strconv"
        "time"
+       "sync"
+       "strings"
 )
 
 //var myClient = &http.Client{Timeout: 1 * time.Second}
@@ -57,8 +59,7 @@ type HttpRestful struct {
        Engine
        LaunchRest                   LaunchRestHandler
        RecvXappCallbackData         RecvXappCallbackDataHandler
-        RecvNewE2Tdata               RecvNewE2TdataHandler
-
+        RecvNewE2Tdata               RecvNewE2TdataHandler 
        ProvideXappHandleHandlerImpl ProvideXappHandleHandlerImpl
        RetrieveStartupData          RetrieveStartupDataHandler
 }
@@ -104,10 +105,17 @@ func recvNewE2Tdata(dataChannel <-chan *models.E2tData) (*rtmgr.E2TInstance, err
         e2tData = <-dataChannel
 
         if nil != e2tData {
-                var e2tinst rtmgr.E2TInstance
-                e2tinst.Fqdn = *e2tData.E2TAddress
-                e2tinst.Name = "E2TERMINST"
-                return &e2tinst,nil
+
+                       e2tinst :=  rtmgr.E2TInstance {
+                                Ranlist : make([]string, len(e2tData.RanNamelist)),
+                       }
+
+            e2tinst.Fqdn = *e2tData.E2TAddress
+            e2tinst.Name = "E2TERMINST"
+                   copy(e2tinst.Ranlist, e2tData.RanNamelist)
+
+            return &e2tinst,nil
+
         } else {
                 xapp.Logger.Info("No data")
         }
@@ -116,9 +124,6 @@ func recvNewE2Tdata(dataChannel <-chan *models.E2tData) (*rtmgr.E2TInstance, err
         return nil, nil
 }
 
-
-
-
 func validateXappCallbackData(callbackData *models.XappCallbackData) error {
        if len(callbackData.XApps) == 0 {
                return fmt.Errorf("invalid Data field: \"%s\"", callbackData.XApps)
@@ -157,18 +162,51 @@ func validateXappSubscriptionData(data *models.XappSubscriptionData) error {
 }
 
 func validateE2tData(data *models.E2tData) error {
-        var err = fmt.Errorf("E2T E2TAddress is not proper: %v", *data.E2TAddress)
-/*      for _, ep := range rtmgr.Eps {
-                if ep.Ip == *data.Address && ep.Port == *data.Port {
-                        err = nil
-                        break
-                }
-        }*/
 
-        if (*data.E2TAddress != "") {
-                err = nil
+       e2taddress_key := *data.E2TAddress
+        if (e2taddress_key == "") {
+                return fmt.Errorf("E2TAddress is empty!!!")
         }
-        return err
+       stringSlice := strings.Split(e2taddress_key, ":")
+       if (len(stringSlice) == 1) {
+               return fmt.Errorf("E2T E2TAddress is not a proper format like ip:port, %v", e2taddress_key )
+       }
+
+       if checkValidaE2TAddress(e2taddress_key) {
+               return fmt.Errorf("E2TAddress already exist!!!, E2TAddress: %v",e2taddress_key)
+       }
+
+       return nil
+}
+
+func validateDeleteE2tData(data *models.E2tDeleteData) error {
+
+        if (*data.E2TAddress == "") {
+                return fmt.Errorf("E2TAddress is empty!!!")
+        }
+
+       for _, element := range data.RanAssocList {
+               e2taddress_key := *element.E2TAddress
+               stringSlice := strings.Split(e2taddress_key, ":")
+
+               if (len(stringSlice) == 1) {
+                       return fmt.Errorf("E2T Delete - RanAssocList E2TAddress is not a proper format like ip:port, %v", e2taddress_key)
+               }
+
+
+               if !checkValidaE2TAddress(e2taddress_key) {
+                               return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v",e2taddress_key)
+               }
+
+       }
+       return nil
+}
+
+func checkValidaE2TAddress(e2taddress string) bool {
+
+       _, exist := rtmgr.Eps[e2taddress]
+       return exist
+
 }
 
 func provideXappSubscriptionHandleImpl(subchan chan<- *models.XappSubscriptionData,
@@ -224,13 +262,68 @@ func createNewE2tHandleHandlerImpl(e2taddchan chan<- *models.E2tData,
                 xapp.Logger.Error(err.Error())
                 return err
         }
-
         e2taddchan <- data
         return nil
 }
 
+func validateE2TAddressRANListData(assRanE2tData models.RanE2tMap) error {
+
+       xapp.Logger.Debug("Invoked.validateE2TAddressRANListData : %v", assRanE2tData)
+
+       for _, element := range assRanE2tData {
+               if *element.E2TAddress == "" {
+                       return fmt.Errorf("E2T Instance - E2TAddress is empty!!!")
+               }
+
+               e2taddress_key := *element.E2TAddress
+               if !checkValidaE2TAddress(e2taddress_key) {
+                       return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v",e2taddress_key)
+               }
+
+       }
+       return nil
+}
+
+func associateRanToE2THandlerImpl(assranchan chan<- models.RanE2tMap,
+        data models.RanE2tMap) error {
+        xapp.Logger.Debug("Invoked associateRanToE2THandlerImpl")
+       err := validateE2TAddressRANListData(data)
+       if err != nil {
+               xapp.Logger.Warn(" Association of RAN to E2T Instance data validation failed: " + err.Error())
+               return err
+       }
+       assranchan <- data
+        return nil
+}
+
+func disassociateRanToE2THandlerImpl(disassranchan chan<- models.RanE2tMap,
+        data models.RanE2tMap) error {
+        xapp.Logger.Debug("Invoked disassociateRanToE2THandlerImpl")
+       err := validateE2TAddressRANListData(data)
+       if err != nil {
+               xapp.Logger.Warn(" Disassociation of RAN List from E2T Instance data validation failed: " + err.Error())
+               return err
+       }
+       disassranchan <- data
+        return nil
+}
+
+func deleteE2tHandleHandlerImpl(e2tdelchan chan<- *models.E2tDeleteData,
+        data *models.E2tDeleteData) error {
+        xapp.Logger.Debug("Invoked deleteE2tHandleHandlerImpl")
+
+        err := validateDeleteE2tData(data)
+        if err != nil {
+                xapp.Logger.Error(err.Error())
+                return err
+        }
+
+        e2tdelchan <- data
+        return nil
+}
+
 func launchRest(nbiif *string, datach chan<- *models.XappCallbackData, subchan chan<- *models.XappSubscriptionData,
-       subdelchan chan<- *models.XappSubscriptionData, e2taddchan chan<- *models.E2tData) {
+       subdelchan chan<- *models.XappSubscriptionData, e2taddchan chan<- *models.E2tData, assranchan chan<- models.RanE2tMap, disassranchan chan<- models.RanE2tMap, e2tdelchan chan<- *models.E2tDeleteData) {
        swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
        if err != nil {
                //log.Fatalln(err)
@@ -297,6 +390,38 @@ func launchRest(nbiif *string, datach chan<- *models.XappCallbackData, subchan c
                         }
                 })
 
+       api.HandleAssociateRanToE2tHandleHandler = handle.AssociateRanToE2tHandleHandlerFunc(
+               func(params handle.AssociateRanToE2tHandleParams) middleware.Responder {
+                        err := associateRanToE2THandlerImpl(assranchan, params.RanE2tList)
+                       if err != nil {
+                                return handle.NewAssociateRanToE2tHandleBadRequest()
+                        } else {
+                               time.Sleep(1 * time.Second)
+                                return handle.NewAssociateRanToE2tHandleCreated()
+                        }
+                })
+
+       api.HandleDissociateRanHandler = handle.DissociateRanHandlerFunc(
+               func(params handle.DissociateRanParams) middleware.Responder {
+                       err := disassociateRanToE2THandlerImpl(disassranchan, params.DissociateList)
+                       if err != nil {
+                                return handle.NewDissociateRanBadRequest()
+                        } else {
+                               time.Sleep(1 * time.Second)
+                                return handle.NewDissociateRanCreated()
+                        }
+                })
+
+       api.HandleDeleteE2tHandleHandler = handle.DeleteE2tHandleHandlerFunc(
+                func(params handle.DeleteE2tHandleParams) middleware.Responder {
+                        err := deleteE2tHandleHandlerImpl(e2tdelchan, params.E2tData)
+                        if err != nil {
+                                return handle.NewDeleteE2tHandleBadRequest()
+                        } else {
+                               time.Sleep(1 * time.Second)
+                                return handle.NewDeleteE2tHandleCreated()
+                        }
+                })
        // start to serve API
        xapp.Logger.Info("Starting the HTTP Rest service")
        if err := server.Serve(); err != nil {
@@ -362,7 +487,7 @@ func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile
 }
 
 func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string,
-       sdlEngine sdl.Engine, rpeEngine rpe.Engine, triggerSBI chan<- bool) error {
+       sdlEngine sdl.Engine, rpeEngine rpe.Engine, triggerSBI chan<- bool, m *sync.Mutex) error {
        err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, sdlEngine)
        if err != nil {
                xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
@@ -373,9 +498,12 @@ func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, co
        subschan := make(chan *models.XappSubscriptionData, 10)
        subdelchan := make(chan *models.XappSubscriptionData, 10)
        e2taddchan := make(chan *models.E2tData, 10)
+       associateranchan := make(chan models.RanE2tMap, 10)
+       disassociateranchan := make(chan models.RanE2tMap, 10)
+       e2tdelchan := make(chan *models.E2tDeleteData, 10)
        xapp.Logger.Info("Launching Rest Http service")
        go func() {
-               r.LaunchRest(&nbiif, datach, subschan, subdelchan, e2taddchan)
+               r.LaunchRest(&nbiif, datach, subschan, subdelchan, e2taddchan, associateranchan, disassociateranchan, e2tdelchan)
        }()
 
        go func() {
@@ -387,7 +515,9 @@ func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, co
                                xapp.Logger.Debug("Fetching all xApps deployed in xApp Manager through GET operation.")
                                alldata, err1 := httpGetXApps(xmurl)
                                if alldata != nil && err1 == nil {
+                                       m.Lock()
                                        sdlEngine.WriteXApps(fileName, alldata)
+                                       m.Unlock()
                                        triggerSBI <- true
                                }
                        }
@@ -416,11 +546,48 @@ func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, co
                 for {
                         xapp.Logger.Debug("received create New E2T data")
 
-                        data, err := r.RecvNewE2Tdata(e2taddchan)
-                        if err != nil {
-                                xapp.Logger.Error("cannot get data from rest api dute to: " + err.Error())
-                        } else if data != nil {
+                        data, _ := r.RecvNewE2Tdata(e2taddchan)
+                        if data != nil {
+                               m.Lock()
                                 sdlEngine.WriteNewE2TInstance(fileName, data)
+                               m.Unlock()
+                                triggerSBI <- true
+                        }
+                }
+        }()
+
+        go func() {
+                for {
+                       data := <-associateranchan
+                        xapp.Logger.Debug("received associate RAN list to E2T instance mapping from E2 Manager")
+                       m.Lock()
+                        sdlEngine.WriteAssRANToE2TInstance(fileName, data)
+                       m.Unlock()
+                        triggerSBI <- true
+                }
+        }()
+
+        go func() {
+                for {
+
+                       data := <-disassociateranchan
+                        xapp.Logger.Debug("received disassociate RANs from E2T instance")
+                       m.Lock()
+                        sdlEngine.WriteDisAssRANFromE2TInstance(fileName, data)
+                       m.Unlock()
+                        triggerSBI <- true
+                }
+        }()
+
+        go func() {
+                for {
+                        xapp.Logger.Debug("received Delete E2T data")
+
+                       data := <-e2tdelchan
+                        if data != nil {
+                               m.Lock()
+                                sdlEngine.WriteDeleteE2TInstance(fileName, data)
+                               m.Unlock()
                                 triggerSBI <- true
                         }
                 }
index cfa644e..465f17b 100644 (file)
@@ -44,6 +44,7 @@ import (
        "routing-manager/pkg/stub"
        "testing"
        "time"
+       "sync"
 
        "github.com/go-openapi/swag"
 )
@@ -172,7 +173,8 @@ func TestHttpInstance(t *testing.T) {
        //ts := createMockAppmgrWithData("127.0.0.1:3000", BasicXAppLists, nil)
        //ts.Start()
        //defer ts.Close()
-       err = httpinstance.Initialize(XMURL, "httpgetter", "rt.json", "config.json", sdlEngine, rpeEngine, triggerSBI)
+       var m sync.Mutex
+       err = httpinstance.Initialize(XMURL, "httpgetter", "rt.json", "config.json", sdlEngine, rpeEngine, triggerSBI, &m)
 }
 
 func TestXappCallbackDataChannelwithdata(t *testing.T) {
index 78f99a5..085486c 100644 (file)
@@ -34,12 +34,13 @@ import (
        "routing-manager/pkg/rpe"
        "routing-manager/pkg/rtmgr"
        "routing-manager/pkg/sdl"
+       "sync"
 )
 
 type FetchAllXAppsHandler func(string) (*[]rtmgr.XApp, error)
 type RecvXappCallbackDataHandler func(<-chan *models.XappCallbackData) (*[]rtmgr.XApp, error)
 type RecvNewE2TdataHandler func(<-chan *models.E2tData) (*rtmgr.E2TInstance, error)
-type LaunchRestHandler func(*string, chan<- *models.XappCallbackData, chan<- *models.XappSubscriptionData, chan<- *models.XappSubscriptionData, chan<- *models.E2tData)
+type LaunchRestHandler func(*string, chan<- *models.XappCallbackData, chan<- *models.XappSubscriptionData, chan<- *models.XappSubscriptionData, chan<- *models.E2tData, chan<- models.RanE2tMap, chan<- models.RanE2tMap, chan<- *models.E2tDeleteData)
 type ProvideXappHandleHandlerImpl func(chan<- *models.XappCallbackData, *models.XappCallbackData) error
 type RetrieveStartupDataHandler func(string, string, string, string, sdl.Engine) error
 
@@ -52,6 +53,6 @@ type EngineConfig struct {
 }
 
 type Engine interface {
-       Initialize(string, string, string, string, sdl.Engine, rpe.Engine, chan<- bool) error
+       Initialize(string, string, string, string, sdl.Engine, rpe.Engine, chan<- bool, *sync.Mutex) error
        Terminate() error
 }
index 6fc8c9f..80323a3 100644 (file)
@@ -34,6 +34,7 @@ import (
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
        "routing-manager/pkg/rtmgr"
        "strconv"
+       "strings"
 )
 
 type Rmr struct {
@@ -52,7 +53,7 @@ func NewRmrPush() *RmrPush {
 /*
 Produces the raw route message consumable by RMR
 */
-func (r *Rmr) generateRMRPolicies(eps rtmgr.Endpoints, key string) *[]string {
+func (r *Rmr) generateRMRPolicies(eps rtmgr.Endpoints, rcs *rtmgr.RicComponents, key string) *[]string {
        rawrt := []string{key + "newrt|start\n"}
        rt := r.generateRouteTable(eps)
        for _, rte := range *rt {
@@ -86,18 +87,31 @@ func (r *Rmr) generateRMRPolicies(eps rtmgr.Endpoints, key string) *[]string {
                rawrt = append(rawrt, rawrte+"\n")
        }
        rawrt = append(rawrt, key+"newrt|end\n")
-
         count := 0
-        rawrt = append(rawrt, key+"meid_map|start\n")
-        rawrt = append(rawrt, key+"meid_map|end|" + strconv.Itoa(count) +"\n")
+       meidrt := key +"meid_map|start\n"
+       for e2tkey, value := range rcs.E2Ts {
+               xapp.Logger.Debug("rmr.E2T Key: %v", e2tkey)
+               xapp.Logger.Debug("rmr.E2T Value: %v", value)
+               xapp.Logger.Debug("rmr.E2T RAN List: %v", rcs.E2Ts[e2tkey].Ranlist)
+               if ( len(rcs.E2Ts[e2tkey].Ranlist) != 0 ) {
+                       ranList := strings.Join(rcs.E2Ts[e2tkey].Ranlist, " ")
+                       meidrt += key + "mme_ar|" + e2tkey + "|" + ranList + "\n"
+                       count++
+               } else {
+               xapp.Logger.Debug("rmr.E2T Empty RAN LIST for FQDN: %v", e2tkey)
+               }
+       }
+        meidrt += key+"meid_map|end|" + strconv.Itoa(count) +"\n"
 
+       rawrt = append(rawrt, meidrt)
        xapp.Logger.Debug("rmr.GeneratePolicies returns: %v", rawrt)
+       xapp.Logger.Debug("rmr.GeneratePolicies returns: %v", rcs)
        return &rawrt
 }
 
-func (r *RmrPush) GeneratePolicies(eps rtmgr.Endpoints) *[]string {
+func (r *RmrPush) GeneratePolicies(eps rtmgr.Endpoints, rcs *rtmgr.RicComponents) *[]string {
        xapp.Logger.Debug("Invoked rmr.GeneratePolicies, args: %v: ", eps)
-       return r.generateRMRPolicies(eps, "")
+       return r.generateRMRPolicies(eps, rcs, "")
 }
 
 func (r *RmrPush) GenerateRouteTable(eps rtmgr.Endpoints) *rtmgr.RouteTable {
index 4538d97..da8da06 100644 (file)
@@ -47,11 +47,12 @@ RmrPush.GeneratePolicies() method is tested for happy path case
 */
 func TestRmrPushGeneratePolicies(t *testing.T) {
        var rmrpush = RmrPush{}
+        var pcs rtmgr.RicComponents
        resetTestDataset(stub.ValidEndpoints)
         stub.ValidPlatformComponents = nil
         rtmgr.Subs =  *stub.ValidSubscriptions
 
-       rawrt := rmrpush.GeneratePolicies(rtmgr.Eps)
+       rawrt := rmrpush.GeneratePolicies(rtmgr.Eps, &pcs)
        t.Log(rawrt)
 }
 
index 9a963c7..11440db 100644 (file)
@@ -163,10 +163,13 @@ func (r *Rpe) generateXappRoutes(xAppEp *rtmgr.Endpoint, e2TermEp *rtmgr.Endpoin
                r.addRoute("RIC_SUB_REQ", xAppEp, subManEp, routeTable, -1, "")
                r.addRoute("RIC_SUB_DEL_REQ", xAppEp, subManEp, routeTable, -1, "")
                //xApp -> E2 Termination
-               r.addRoute("RIC_CONTROL_REQ", xAppEp, e2TermEp, routeTable, -1, "")
+//             r.addRoute("RIC_CONTROL_REQ", xAppEp, e2TermEp, routeTable, -1, "")
+               r.addRoute("RIC_CONTROL_REQ", xAppEp, nil, routeTable, -1, "%meid")
                //E2 Termination -> xApp
-               r.addRoute("RIC_CONTROL_ACK", e2TermEp, xAppEp, routeTable, -1, "")
-               r.addRoute("RIC_CONTROL_FAILURE", e2TermEp, xAppEp, routeTable, -1, "")
+///            r.addRoute("RIC_CONTROL_ACK", e2TermEp, xAppEp, routeTable, -1, "")
+///            r.addRoute("RIC_CONTROL_FAILURE", e2TermEp, xAppEp, routeTable, -1, "")
+               r.addRoute("RIC_CONTROL_ACK", nil, xAppEp, routeTable, -1, "")
+               r.addRoute("RIC_CONTROL_FAILURE", nil, xAppEp, routeTable, -1, "")
        }
        //xApp->A1Mediator
        if xAppEp.XAppType != sbi.PlatformType && len(xAppEp.Policies) > 0 {
index 626213e..4a5b9fc 100644 (file)
@@ -43,6 +43,6 @@ type EngineConfig struct {
 }
 
 type Engine interface {
-       GeneratePolicies(rtmgr.Endpoints) *[]string
+       GeneratePolicies(rtmgr.Endpoints, *rtmgr.RicComponents) *[]string
        GenerateRouteTable(rtmgr.Endpoints) *rtmgr.RouteTable
 }
index b4f1e8e..969f7bd 100644 (file)
@@ -35,6 +35,7 @@ import (
        "io/ioutil"
        "os"
        "routing-manager/pkg/rtmgr"
+       "routing-manager/pkg/models"
 )
 
 /*
@@ -60,11 +61,11 @@ func (f *File) ReadAll(file string) (*rtmgr.RicComponents, error) {
                return nil, errors.New("cannot open the file due to: " + err.Error())
        }
        defer jsonFile.Close()
-
        byteValue, err := ioutil.ReadAll(jsonFile)
        if err != nil {
                return nil, errors.New("cannot read the file due to: " + err.Error())
        }
+
        err = json.Unmarshal(byteValue, &rcs)
        if err != nil {
                return nil, errors.New("cannot parse data due to: " + err.Error())
@@ -133,3 +134,127 @@ func (f *File) WriteNewE2TInstance(file string, E2TInst *rtmgr.E2TInstance) erro
         }
         return nil
 }
+
+func (f *File) WriteAssRANToE2TInstance(file string, rane2tmap models.RanE2tMap) error {
+        xapp.Logger.Debug("Invoked sdl.WriteAssRANToE2TInstance")
+        xapp.Logger.Debug("file.WriteAssRANToE2TInstance writes into file: " + file)
+        xapp.Logger.Debug("file.WriteAssRANToE2TInstance writes data: %v", rane2tmap)
+
+        ricData, err := NewFile().ReadAll(file)
+        if err != nil {
+                xapp.Logger.Error("cannot get data from sdl interface due to: " + err.Error())
+                return errors.New("cannot read full ric data to modify xApps data, due to:  " + err.Error())
+        }
+       for _, element := range rane2tmap {
+               xapp.Logger.Info("data received")
+               for key, _ := range ricData.E2Ts {
+                       if key == *element.E2TAddress {
+                               var estObj rtmgr.E2TInstance
+                               estObj = ricData.E2Ts[key]
+                               estObj.Ranlist = append(ricData.E2Ts[key].Ranlist, element.RanNamelist...)
+                               ricData.E2Ts[key]= estObj
+                       }
+               }
+       }
+
+       byteValue, err := json.Marshal(ricData)
+        if err != nil {
+                return errors.New("cannot convert data due to: " + err.Error())
+        }
+        err = ioutil.WriteFile(file, byteValue, 0644)
+        if err != nil {
+                return errors.New("cannot write file due to: " + err.Error())
+        }
+        return nil
+}
+
+func (f *File) WriteDisAssRANFromE2TInstance(file string, disassranmap models.RanE2tMap) error {
+        xapp.Logger.Debug("Invoked sdl.WriteDisAssRANFromE2TInstance")
+        xapp.Logger.Debug("file.WriteDisAssRANFromE2TInstance writes into file: " + file)
+        xapp.Logger.Debug("file.WriteDisAssRANFromE2TInstance writes data: %v", disassranmap)
+
+        ricData, err := NewFile().ReadAll(file)
+        if err != nil {
+                xapp.Logger.Error("cannot get data from sdl interface due to: " + err.Error())
+                return errors.New("cannot read full ric data to modify xApps data, due to:  " + err.Error())
+        }
+       for _, element := range disassranmap {
+               xapp.Logger.Info("data received")
+               e2taddress_key := *element.E2TAddress
+               //Check whether the provided E2T Address is available in SDL as a key. 
+               //If exist, proceed further to check RAN list, Otherwise move to next E2T Instance
+               if _, exist := ricData.E2Ts[e2taddress_key]; exist {
+                       var estObj rtmgr.E2TInstance
+                       estObj = ricData.E2Ts[e2taddress_key]
+                       // If RAN list is empty, then routing manager assumes that all RANs attached associated to the particular E2T Instance to be removed.
+                       if len(element.RanNamelist) == 0 {
+                               xapp.Logger.Debug("RAN List is empty. So disassociating all RANs from the E2T Instance: %v ", *element.E2TAddress)
+                               estObj.Ranlist = []string{}
+                       } else {
+                               xapp.Logger.Debug("Remove only selected rans from E2T Instance: %v and %v ", ricData.E2Ts[e2taddress_key].Ranlist, element.RanNamelist)
+                               for _, disRanValue := range element.RanNamelist {
+                                       for ranIndex, ranValue := range ricData.E2Ts[e2taddress_key].Ranlist {
+                                               if disRanValue == ranValue {
+                                                       estObj.Ranlist[ranIndex] = estObj.Ranlist[len(estObj.Ranlist)-1]
+                                                       estObj.Ranlist[len(estObj.Ranlist)-1] = ""
+                                                       estObj.Ranlist = estObj.Ranlist[:len(estObj.Ranlist)-1]
+                                               }
+                                       }
+                               }
+                       }
+                       ricData.E2Ts[e2taddress_key]= estObj
+               }
+       }
+
+       xapp.Logger.Debug("Final data after disassociate: %v", ricData)
+
+       byteValue, err := json.Marshal(ricData)
+        if err != nil {
+                return errors.New("cannot convert data due to: " + err.Error())
+        }
+        err = ioutil.WriteFile(file, byteValue, 0644)
+        if err != nil {
+                return errors.New("cannot write file due to: " + err.Error())
+        }
+       return nil
+}
+
+func (f *File) WriteDeleteE2TInstance(file string, E2TInst *models.E2tDeleteData) error {
+       xapp.Logger.Debug("Invoked sdl.WriteDeleteE2TInstance")
+       xapp.Logger.Debug("file.WriteDeleteE2TInstance writes into file: " + file)
+       xapp.Logger.Debug("file.WriteDeleteE2TInstance writes data: %v", *E2TInst)
+
+       ricData, err := NewFile().ReadAll(file)
+       if err != nil {
+               xapp.Logger.Error("cannot get data from sdl interface due to: " + err.Error())
+               return errors.New("cannot read full ric data to modify xApps data, due to:  " + err.Error())
+       }
+
+       delete(ricData.E2Ts, *E2TInst.E2TAddress)
+
+
+       for _, element := range E2TInst.RanAssocList {
+               xapp.Logger.Info("data received")
+               key := *element.E2TAddress
+
+               if val, ok := ricData.E2Ts[key]; ok {
+                       var estObj rtmgr.E2TInstance
+                       estObj = val
+                       estObj.Ranlist = append(ricData.E2Ts[key].Ranlist, element.RanNamelist...)
+                       ricData.E2Ts[key]= estObj
+               } else {
+                       xapp.Logger.Error("file.WriteDeleteE2TInstance E2T instance is not found for provided E2TAddress : %v", errors.New(key).Error())
+               }
+
+       }
+
+       byteValue, err := json.Marshal(ricData)
+       if err != nil {
+               return errors.New("cannot convert data due to: " + err.Error())
+       }
+       err = ioutil.WriteFile(file, byteValue, 0644)
+       if err != nil {
+               return errors.New("cannot write file due to: " + err.Error())
+       }
+       return nil
+}
index f94557e..f4a9125 100644 (file)
@@ -28,6 +28,7 @@
 package sdl
 
 import "routing-manager/pkg/rtmgr"
+import "routing-manager/pkg/models" 
 
 //type readAll func(string) (*rtmgr.RicComponents, error)
 //type writeAll func(string, *rtmgr.RicComponents) error
@@ -45,4 +46,7 @@ type Engine interface {
        WriteAll(string, *rtmgr.RicComponents) error
        WriteXApps(string, *[]rtmgr.XApp) error
        WriteNewE2TInstance(string, *rtmgr.E2TInstance) error
+       WriteAssRANToE2TInstance(string, models.RanE2tMap) error
+       WriteDisAssRANFromE2TInstance(string, models.RanE2tMap) error
+       WriteDeleteE2TInstance(string, *models.E2tDeleteData) error
 }