Fixed bug: MEID table not getting built during rtmgr restart; MEID table
[ric-plt/rtmgr.git] / pkg / nbi / httprestful.go
index a9aeaa2..5223162 100644 (file)
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
+
+
+   This source code is part of the near-RT RIC (RAN Intelligent Controller)
+   platform project (RICP).
+
 ==================================================================================
 */
 /*
 ==================================================================================
 */
 /*
@@ -30,64 +35,83 @@ import (
        "encoding/json"
        "errors"
        "fmt"
        "encoding/json"
        "errors"
        "fmt"
-       "github.com/go-openapi/loads"
-       "github.com/go-openapi/runtime/middleware"
-       "net/url"
-       "os"
+       xfmodel "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+       //"github.com/go-openapi/loads"
+       //"github.com/go-openapi/runtime/middleware"
+       "net"
+       //"net/url"
+       //"os"
        "routing-manager/pkg/models"
        "routing-manager/pkg/models"
-       "routing-manager/pkg/restapi"
-       "routing-manager/pkg/restapi/operations"
-       "routing-manager/pkg/restapi/operations/handle"
+       //"routing-manager/pkg/restapi"
+       //"routing-manager/pkg/restapi/operations"
+       //"routing-manager/pkg/restapi/operations/debug"
+       //"routing-manager/pkg/restapi/operations/handle"
        "routing-manager/pkg/rpe"
        "routing-manager/pkg/rtmgr"
        "routing-manager/pkg/sdl"
        "strconv"
        "routing-manager/pkg/rpe"
        "routing-manager/pkg/rtmgr"
        "routing-manager/pkg/sdl"
        "strconv"
+       "strings"
+       "sync"
        "time"
 )
 
        "time"
 )
 
-//var myClient = &http.Client{Timeout: 1 * time.Second}
-
 type HttpRestful struct {
        Engine
 type HttpRestful struct {
        Engine
-       LaunchRest                   LaunchRestHandler
-       RecvXappCallbackData         RecvXappCallbackDataHandler
-       ProvideXappHandleHandlerImpl ProvideXappHandleHandlerImpl
-       RetrieveStartupData          RetrieveStartupDataHandler
+       //LaunchRest          LaunchRestHandler
+       RetrieveStartupData RetrieveStartupDataHandler
 }
 
 func NewHttpRestful() *HttpRestful {
        instance := new(HttpRestful)
 }
 
 func NewHttpRestful() *HttpRestful {
        instance := new(HttpRestful)
-       instance.LaunchRest = launchRest
-       instance.RecvXappCallbackData = recvXappCallbackData
-       instance.ProvideXappHandleHandlerImpl = provideXappHandleHandlerImpl
+       //instance.LaunchRest = launchRest
        instance.RetrieveStartupData = retrieveStartupData
        return instance
 }
 
        instance.RetrieveStartupData = retrieveStartupData
        return instance
 }
 
-// ToDo: Use Range over channel. Read and return only the latest one.
-func recvXappCallbackData(dataChannel <-chan *models.XappCallbackData) (*[]rtmgr.XApp, error) {
-       var xappData *models.XappCallbackData
-       // Drain the channel as we are only looking for the latest value until
-       // xapp manager sends all xapp data with every request.
-       length := len(dataChannel)
-       //rtmgr.Logger.Info(length)
-       for i := 0; i <= length; i++ {
-               rtmgr.Logger.Info("data received")
-               // If no data received from the REST, it blocks.
-               xappData = <-dataChannel
-       }
+func recvXappCallbackData(xappData *models.XappCallbackData) (*[]rtmgr.XApp, error) {
        if nil != xappData {
                var xapps []rtmgr.XApp
                err := json.Unmarshal([]byte(xappData.XApps), &xapps)
                return &xapps, err
        } else {
        if nil != xappData {
                var xapps []rtmgr.XApp
                err := json.Unmarshal([]byte(xappData.XApps), &xapps)
                return &xapps, err
        } else {
-               rtmgr.Logger.Info("No data")
+               xapp.Logger.Info("No data")
        }
 
        }
 
-       rtmgr.Logger.Debug("Nothing received on the Http interface")
+       xapp.Logger.Debug("Nothing received on the Http interface")
        return nil, nil
 }
 
        return nil, nil
 }
 
+func recvNewE2Tdata(e2tData *models.E2tData) (*rtmgr.E2TInstance, string, error) {
+       var str string
+       xapp.Logger.Info("data received")
+
+       if nil != e2tData {
+
+               e2tinst := rtmgr.E2TInstance{
+                       Ranlist: make([]string, len(e2tData.RanNamelist)),
+               }
+
+               e2tinst.Fqdn = *e2tData.E2TAddress
+               e2tinst.Name = "E2TERMINST"
+               copy(e2tinst.Ranlist, e2tData.RanNamelist)
+               if len(e2tData.RanNamelist) > 0 {
+                       var meidar string
+                       for _, meid := range e2tData.RanNamelist {
+                               meidar += meid + " "
+                       }
+                       str = "mme_ar|" + *e2tData.E2TAddress + "|" + strings.TrimSuffix(meidar, " ")
+               }
+               return &e2tinst, str, nil
+
+       } else {
+               xapp.Logger.Info("No data")
+       }
+
+       xapp.Logger.Debug("Nothing received on the Http interface")
+       return nil, str, nil
+}
+
 func validateXappCallbackData(callbackData *models.XappCallbackData) error {
        if len(callbackData.XApps) == 0 {
                return fmt.Errorf("invalid Data field: \"%s\"", callbackData.XApps)
 func validateXappCallbackData(callbackData *models.XappCallbackData) error {
        if len(callbackData.XApps) == 0 {
                return fmt.Errorf("invalid Data field: \"%s\"", callbackData.XApps)
@@ -100,16 +124,32 @@ func validateXappCallbackData(callbackData *models.XappCallbackData) error {
        return nil
 }
 
        return nil
 }
 
-func provideXappHandleHandlerImpl(datach chan<- *models.XappCallbackData, data *models.XappCallbackData) error {
-       if data != nil {
-               rtmgr.Logger.Debug("Received callback data")
+func ProvideXappHandleHandlerImpl(data *models.XappCallbackData) error {
+       if data == nil {
+               xapp.Logger.Debug("Received callback data")
+               return nil
        }
        err := validateXappCallbackData(data)
        if err != nil {
        }
        err := validateXappCallbackData(data)
        if err != nil {
-               rtmgr.Logger.Warn("XApp callback data validation failed: " + err.Error())
+               xapp.Logger.Warn("XApp callback data validation failed: " + err.Error())
                return err
        } else {
                return err
        } else {
-               datach <- data
+               appdata, err := recvXappCallbackData(data)
+               if err != nil {
+                       xapp.Logger.Error("cannot get data from rest api dute to: " + err.Error())
+               } else if appdata != nil {
+                       xapp.Logger.Debug("Fetching all xApps deployed in xApp Manager through GET operation.")
+                       alldata, err1 := httpGetXApps(xapp.Config.GetString("xmurl"))
+                       if alldata != nil && err1 == nil {
+                               m.Lock()
+                               sdlEngine.WriteXApps(xapp.Config.GetString("rtfile"), alldata)
+                               m.Unlock()
+                               updateEp()
+                               return sendRoutesToAll()
+                               //return sendPartialRoutesToAll(nil, rtmgr.XappType)
+                       }
+               }
+
                return nil
        }
 }
                return nil
        }
 }
@@ -125,18 +165,70 @@ func validateXappSubscriptionData(data *models.XappSubscriptionData) error {
        return err
 }
 
        return err
 }
 
-func provideXappSubscriptionHandleImpl(subchan chan<- *models.XappSubscriptionData,
-       data *models.XappSubscriptionData) error {
-       rtmgr.Logger.Debug("Invoked provideXappSubscriptionHandleImpl")
+func validateE2tData(data *models.E2tData) (error, bool) {
+
+       e2taddress_key := *data.E2TAddress
+       if e2taddress_key == "" {
+               return fmt.Errorf("E2TAddress is empty!!!"), false
+       }
+       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), false
+       }
+
+       _, err := net.LookupIP(stringSlice[0])
+       if err != nil {
+               return fmt.Errorf("E2T E2TAddress DNS look up failed, E2TAddress: %v", stringSlice[0]), false
+       }
+
+       if checkValidaE2TAddress(e2taddress_key) {
+               return fmt.Errorf("E2TAddress already exist!!!, E2TAddress: %v", e2taddress_key), true
+       }
+
+       return nil, false
+}
+
+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(data *models.XappSubscriptionData) error {
+       xapp.Logger.Debug("Invoked provideXappSubscriptionHandleImpl")
        err := validateXappSubscriptionData(data)
        if err != nil {
        err := validateXappSubscriptionData(data)
        if err != nil {
-               rtmgr.Logger.Error(err.Error())
+               xapp.Logger.Error(err.Error())
                return err
        }
                return err
        }
-       subchan <- data
-       //var val = string(*data.Address + ":" + strconv.Itoa(int(*data.Port)))
-       rtmgr.Logger.Debug("Endpoints: %v", rtmgr.Eps)
-       return nil
+       xapp.Logger.Debug("received XApp subscription data")
+       addSubscription(&rtmgr.Subs, data)
+       xapp.Logger.Debug("Endpoints: %v", rtmgr.Eps)
+       updateEp()
+       return sendPartialRoutesToAll(data, rtmgr.SubsType)
 }
 
 func subscriptionExists(data *models.XappSubscriptionData) bool {
 }
 
 func subscriptionExists(data *models.XappSubscriptionData) bool {
@@ -151,87 +243,177 @@ func subscriptionExists(data *models.XappSubscriptionData) bool {
        return present
 }
 
        return present
 }
 
-func deleteXappSubscriptionHandleImpl(subdelchan chan<- *models.XappSubscriptionData,
-       data *models.XappSubscriptionData) error {
-       rtmgr.Logger.Debug("Invoked deleteXappSubscriptionHandleImpl")
+func DeleteXappSubscriptionHandleImpl(data *models.XappSubscriptionData) error {
+       xapp.Logger.Debug("Invoked deleteXappSubscriptionHandleImpl")
        err := validateXappSubscriptionData(data)
        if err != nil {
        err := validateXappSubscriptionData(data)
        if err != nil {
-               rtmgr.Logger.Error(err.Error())
+               xapp.Logger.Error(err.Error())
                return err
        }
 
        if !subscriptionExists(data) {
                return err
        }
 
        if !subscriptionExists(data) {
-               rtmgr.Logger.Warn("subscription not found: %d", *data.SubscriptionID)
+               xapp.Logger.Warn("subscription not found: %d", *data.SubscriptionID)
                err := fmt.Errorf("subscription not found: %d", *data.SubscriptionID)
                return err
        }
 
                err := fmt.Errorf("subscription not found: %d", *data.SubscriptionID)
                return err
        }
 
-       subdelchan <- data
+       xapp.Logger.Debug("received XApp subscription delete data")
+       delSubscription(&rtmgr.Subs, data)
+       updateEp()
+       return sendRoutesToAll()
+
+}
+
+func UpdateXappSubscriptionHandleImpl(data *models.XappList, subid uint16) error {
+       xapp.Logger.Debug("Invoked updateXappSubscriptionHandleImpl")
+
+       var fqdnlist []rtmgr.FqDn
+       for _, item := range *data {
+               fqdnlist = append(fqdnlist, rtmgr.FqDn(*item))
+       }
+       xapplist := rtmgr.XappList{SubscriptionID: subid, FqdnList: fqdnlist}
+       var subdata models.XappSubscriptionData
+       var id int32
+       id = int32(subid)
+       subdata.SubscriptionID = &id
+       for _, items := range fqdnlist {
+               subdata.Address = items.Address
+               subdata.Port = items.Port
+               err := validateXappSubscriptionData(&subdata)
+               if err != nil {
+                       xapp.Logger.Error(err.Error())
+                       return err
+               }
+       }
+       xapp.Logger.Debug("received XApp subscription Merge data")
+       updateSubscription(&xapplist)
+       updateEp()
+       return sendRoutesToAll()
+}
+
+func CreateNewE2tHandleHandlerImpl(data *models.E2tData) error {
+       xapp.Logger.Debug("Invoked createNewE2tHandleHandlerImpl")
+       err, IsDuplicate := validateE2tData(data)
+       if IsDuplicate == true {
+               updateEp()
+               //return sendPartialRoutesToAll(nil, rtmgr.E2Type)
+               return sendRoutesToAll()
+       }
+
+       if err != nil {
+               xapp.Logger.Error(err.Error())
+               return err
+       }
+       //e2taddchan <- data
+       e2data, meiddata, _ := recvNewE2Tdata(data)
+       xapp.Logger.Debug("received create New E2T data")
+       m.Lock()
+       sdlEngine.WriteNewE2TInstance(xapp.Config.GetString("rtfile"), e2data, meiddata)
+       m.Unlock()
+       updateEp()
+       //sendPartialRoutesToAll(nil, rtmgr.E2Type)
+       sendRoutesToAll()
+       time.Sleep(10 * time.Second)
+       for ep, value := range rtmgr.RMRConnStatus {
+               if ep == *data.E2TAddress && value == true {
+                       return nil
+               }
+       }
+
+       return errors.New("Error while adding new E2T " + *data.E2TAddress)
+
+}
+
+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
 }
 
        return nil
 }
 
-func launchRest(nbiif *string, datach chan<- *models.XappCallbackData, subchan chan<- *models.XappSubscriptionData,
-       subdelchan chan<- *models.XappSubscriptionData) {
-       swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
+func AssociateRanToE2THandlerImpl(data models.RanE2tMap) error {
+       xapp.Logger.Debug("Invoked associateRanToE2THandlerImpl")
+       err := validateE2TAddressRANListData(data)
        if err != nil {
        if err != nil {
-               //log.Fatalln(err)
-               rtmgr.Logger.Error(err.Error())
-               os.Exit(1)
+               xapp.Logger.Warn(" Association of RAN to E2T Instance data validation failed: " + err.Error())
+               return err
        }
        }
-       nbiUrl, err := url.Parse(*nbiif)
+       xapp.Logger.Debug("received associate RAN list to E2T instance mapping from E2 Manager")
+       m.Lock()
+       sdlEngine.WriteAssRANToE2TInstance(xapp.Config.GetString("rtfile"), data)
+       m.Unlock()
+       updateEp()
+       return sendRoutesToAll()
+
+}
+
+func DisassociateRanToE2THandlerImpl(data models.RanE2tMap) error {
+       xapp.Logger.Debug("Invoked disassociateRanToE2THandlerImpl")
+       err := validateE2TAddressRANListData(data)
        if err != nil {
        if err != nil {
-               rtmgr.Logger.Error(err.Error())
-               os.Exit(1)
+               xapp.Logger.Warn(" Disassociation of RAN List from E2T Instance data validation failed: " + err.Error())
+               return err
        }
        }
-       api := operations.NewRoutingManagerAPI(swaggerSpec)
-       server := restapi.NewServer(api)
-       defer server.Shutdown()
+       xapp.Logger.Debug("received disassociate RANs from E2T instance")
+       m.Lock()
+       sdlEngine.WriteDisAssRANFromE2TInstance(xapp.Config.GetString("rtfile"), data)
+       m.Unlock()
+       updateEp()
+       return sendRoutesToAll()
+
+}
 
 
-       server.Port, err = strconv.Atoi(nbiUrl.Port())
+func DeleteE2tHandleHandlerImpl(data *models.E2tDeleteData) error {
+       xapp.Logger.Debug("Invoked deleteE2tHandleHandlerImpl")
+
+       err := validateDeleteE2tData(data)
        if err != nil {
        if err != nil {
-               rtmgr.Logger.Error("Invalid NBI RestAPI port")
-               os.Exit(1)
-       }
-       server.Host = "0.0.0.0"
-       // set handlers
-       api.HandleProvideXappHandleHandler = handle.ProvideXappHandleHandlerFunc(
-               func(params handle.ProvideXappHandleParams) middleware.Responder {
-                       rtmgr.Logger.Info("Data received on Http interface")
-                       err := provideXappHandleHandlerImpl(datach, params.XappCallbackData)
-                       if err != nil {
-                               rtmgr.Logger.Error("Invalid XApp callback data: " + err.Error())
-                               return handle.NewProvideXappHandleBadRequest()
-                       } else {
-                               return handle.NewGetHandlesOK()
-                       }
-               })
-       api.HandleProvideXappSubscriptionHandleHandler = handle.ProvideXappSubscriptionHandleHandlerFunc(
-               func(params handle.ProvideXappSubscriptionHandleParams) middleware.Responder {
-                       err := provideXappSubscriptionHandleImpl(subchan, params.XappSubscriptionData)
-                       if err != nil {
-                               return handle.NewProvideXappSubscriptionHandleBadRequest()
-                       } else {
-                               return handle.NewGetHandlesOK()
-                       }
-               })
-       api.HandleDeleteXappSubscriptionHandleHandler = handle.DeleteXappSubscriptionHandleHandlerFunc(
-               func(params handle.DeleteXappSubscriptionHandleParams) middleware.Responder {
-                       err := deleteXappSubscriptionHandleImpl(subdelchan, params.XappSubscriptionData)
-                       if err != nil {
-                               return handle.NewDeleteXappSubscriptionHandleNoContent()
-                       } else {
-                               return handle.NewGetHandlesOK()
-                       }
-               })
-       // start to serve API
-       rtmgr.Logger.Info("Starting the HTTP Rest service")
-       if err := server.Serve(); err != nil {
-               rtmgr.Logger.Error(err.Error())
+               xapp.Logger.Error(err.Error())
+               return err
        }
        }
+       m.Lock()
+       sdlEngine.WriteDeleteE2TInstance(xapp.Config.GetString("rtfile"), data)
+       m.Unlock()
+       updateEp()
+       return sendRoutesToAll()
+
+}
+
+func DumpDebugData() (models.Debuginfo, error) {
+       var response models.Debuginfo
+       sdlEngine, _ := sdl.GetSdl("file")
+       rpeEngine, _ := rpe.GetRpe("rmrpush")
+       data, err := sdlEngine.ReadAll(xapp.Config.GetString("rtfile"))
+       if data == nil {
+               if err != nil {
+                       xapp.Logger.Error("Cannot get data from sdl interface due to: " + err.Error())
+                       return response, err
+               } else {
+                       xapp.Logger.Debug("Cannot get data from sdl interface")
+                       return response, errors.New("Cannot get data from sdl interface")
+               }
+       }
+       response.RouteTable = *rpeEngine.GeneratePolicies(rtmgr.Eps, data)
+
+       prettyJSON, err := json.MarshalIndent(data, "", "")
+       response.RouteConfigs = string(prettyJSON)
+
+       return response, err
 }
 
 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
 }
 
 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
-       rtmgr.Logger.Info("Invoked httpgetter.fetchXappList: " + xmurl)
+       xapp.Logger.Info("Invoked httprestful.httpGetXApps: " + xmurl)
        r, err := myClient.Get(xmurl)
        if err != nil {
                return nil, err
        r, err := myClient.Get(xmurl)
        if err != nil {
                return nil, err
@@ -239,99 +421,188 @@ func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
        defer r.Body.Close()
 
        if r.StatusCode == 200 {
        defer r.Body.Close()
 
        if r.StatusCode == 200 {
-               rtmgr.Logger.Debug("http client raw response: %v", r)
+               xapp.Logger.Debug("http client raw response: %v", r)
                var xapps []rtmgr.XApp
                err = json.NewDecoder(r.Body).Decode(&xapps)
                if err != nil {
                var xapps []rtmgr.XApp
                err = json.NewDecoder(r.Body).Decode(&xapps)
                if err != nil {
-                       rtmgr.Logger.Warn("Json decode failed: " + err.Error())
+                       xapp.Logger.Warn("Json decode failed: " + err.Error())
                }
                }
-               rtmgr.Logger.Info("HTTP GET: OK")
-               rtmgr.Logger.Debug("httpgetter.fetchXappList returns: %v", xapps)
+               xapp.Logger.Info("HTTP GET: OK")
+               xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", xapps)
                return &xapps, err
        }
                return &xapps, err
        }
-       rtmgr.Logger.Warn("httpgetter got an unexpected http status code: %v", r.StatusCode)
+       xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
        return nil, nil
 }
 
        return nil, nil
 }
 
-func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, sdlEngine sdl.Engine) error {
+func httpGetE2TList(e2murl string) (*[]rtmgr.E2tIdentity, error) {
+       xapp.Logger.Info("Invoked httprestful.httpGetE2TList: " + e2murl)
+       r, err := myClient.Get(e2murl)
+       if err != nil {
+               return nil, err
+       }
+       defer r.Body.Close()
+
+       if r.StatusCode == 200 {
+               xapp.Logger.Debug("http client raw response: %v", r)
+               var E2Tlist []rtmgr.E2tIdentity
+               err = json.NewDecoder(r.Body).Decode(&E2Tlist)
+               if err != nil {
+                       xapp.Logger.Warn("Json decode failed: " + err.Error())
+               }
+               xapp.Logger.Info("HTTP GET: OK")
+               xapp.Logger.Debug("httprestful.httpGetE2TList returns: %v", E2Tlist)
+               return &E2Tlist, err
+       }
+       xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
+       return nil, nil
+}
+
+func PopulateE2TMap(e2tDataList *[]rtmgr.E2tIdentity, e2ts map[string]rtmgr.E2TInstance, meids *[]string) {
+       xapp.Logger.Info("Invoked httprestful.PopulateE2TMap ")
+
+       for _, e2tData := range *e2tDataList {
+               var str string
+
+               e2tinst := rtmgr.E2TInstance{
+                       Ranlist: make([]string, len(e2tData.Rannames)),
+               }
+
+               e2tinst.Fqdn = e2tData.E2taddress
+               e2tinst.Name = "E2TERMINST"
+               copy(e2tinst.Ranlist, e2tData.Rannames)
+
+               if len(e2tData.Rannames) > 0 {
+                       var meidar string
+                       for _, meid := range e2tData.Rannames {
+                               meidar += meid + " "
+                       }
+                       str = "mme_ar|" + e2tData.E2taddress + "|" + strings.TrimSuffix(meidar, " ")
+                   *meids = append(*meids, str)
+               }
+
+               e2ts[e2tinst.Fqdn] = e2tinst
+       }
+    xapp.Logger.Info("MEID's retrieved are %v", *meids)
+}
+
+func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, e2murl string, sdlEngine sdl.Engine) error {
+       xapp.Logger.Info("Invoked retrieveStartupData ")
        var readErr error
        var readErr error
+       var err error
        var maxRetries = 10
        var maxRetries = 10
+       var xappData *[]rtmgr.XApp
+       xappData = new([]rtmgr.XApp)
+       xapp.Logger.Info("Trying to fetch XApps data from XAPP manager")
        for i := 1; i <= maxRetries; i++ {
                time.Sleep(2 * time.Second)
        for i := 1; i <= maxRetries; i++ {
                time.Sleep(2 * time.Second)
-               xappData, err := httpGetXApps(xmurl)
+
+               readErr = nil
+               xappData, err = httpGetXApps(xmurl)
                if xappData != nil && err == nil {
                if xappData != nil && err == nil {
-                       pcData, confErr := rtmgr.GetPlatformComponents(configfile)
-                       if confErr != nil {
-                               rtmgr.Logger.Error(confErr.Error())
-                               return confErr
-                       }
-                       rtmgr.Logger.Info("Recieved intial xapp data and platform data, writing into SDL.")
-                       // Combine the xapps data and platform data before writing to the SDL
-                       ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData}
-                       writeErr := sdlEngine.WriteAll(fileName, ricData)
-                       if writeErr != nil {
-                               rtmgr.Logger.Error(writeErr.Error())
-                       }
-                       // post subscription req to appmgr
-                       readErr = PostSubReq(xmurl, nbiif)
-                       if readErr == nil {
-                               return nil
-                       }
+                       break
                } else if err == nil {
                        readErr = errors.New("unexpected HTTP status code")
                } else {
                } else if err == nil {
                        readErr = errors.New("unexpected HTTP status code")
                } else {
-                       rtmgr.Logger.Warn("cannot get xapp data due to: " + err.Error())
+                       xapp.Logger.Warn("cannot get xapp data due to: " + err.Error())
                        readErr = err
                }
        }
                        readErr = err
                }
        }
-       return readErr
-}
 
 
-func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string,
-       sdlEngine sdl.Engine, rpeEngine rpe.Engine, triggerSBI chan<- bool) error {
-       err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, sdlEngine)
-       if err != nil {
-               rtmgr.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
-               return err
+       if readErr != nil {
+               return readErr
        }
 
        }
 
-       datach := make(chan *models.XappCallbackData, 10)
-       subschan := make(chan *models.XappSubscriptionData, 10)
-       subdelchan := make(chan *models.XappSubscriptionData, 10)
-       rtmgr.Logger.Info("Launching Rest Http service")
-       go func() {
-               r.LaunchRest(&nbiif, datach, subschan, subdelchan)
-       }()
-
-       go func() {
-               for {
-                       data, err := r.RecvXappCallbackData(datach)
-                       if err != nil {
-                               rtmgr.Logger.Error("cannot get data from rest api dute to: " + err.Error())
-                       } else if data != nil {
-                               sdlEngine.WriteXApps(fileName, data)
-                               triggerSBI <- true
-                       }
+       var meids []string
+       e2ts := make(map[string]rtmgr.E2TInstance)
+       xapp.Logger.Info("Trying to fetch E2T data from E2manager")
+       for i := 1; i <= maxRetries; i++ {
+
+               readErr = nil
+               e2tDataList, err := httpGetE2TList(e2murl)
+               if e2tDataList != nil && err == nil {
+                       PopulateE2TMap(e2tDataList, e2ts, &meids)
+                       break
+               } else if err == nil {
+                       readErr = errors.New("unexpected HTTP status code")
+               } else {
+                       xapp.Logger.Warn("cannot get E2T data from E2M due to: " + err.Error())
+                       readErr = err
                }
                }
-       }()
-
-       go func() {
-               for {
-                       data := <-subschan
-                       rtmgr.Logger.Debug("received XApp subscription data")
-                       addSubscription(&rtmgr.Subs, data)
-                       triggerSBI <- true
+               time.Sleep(2 * time.Second)
+       }
+
+       if readErr != nil {
+               return readErr
+       }
+
+       pcData, confErr := rtmgr.GetPlatformComponents(configfile)
+       if confErr != nil {
+               xapp.Logger.Error(confErr.Error())
+               return confErr
+       }
+       xapp.Logger.Info("Recieved intial xapp data, E2T data and platform data, writing into SDL.")
+       // Combine the xapps data and platform data before writing to the SDL
+       ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts: e2ts, MeidMap: meids}
+       writeErr := sdlEngine.WriteAll(fileName, ricData)
+       if writeErr != nil {
+               xapp.Logger.Error(writeErr.Error())
+       }
+
+       xapp.Logger.Info("Trying to fetch Subscriptions data from Subscription manager")
+       for i := 1; i <= maxRetries; i++ {
+               readErr = nil
+               sub_list, err := xapp.Subscription.QuerySubscriptions()
+
+               if sub_list != nil && err == nil {
+                       PopulateSubscription(sub_list)
+                       break
+               } else {
+                       readErr = err
+                       xapp.Logger.Warn("cannot get xapp data due to: " + readErr.Error())
                }
                }
-       }()
-
-       go func() {
-               for {
-                       data := <-subdelchan
-                       rtmgr.Logger.Debug("received XApp subscription delete data")
-                       delSubscription(&rtmgr.Subs, data)
-                       triggerSBI <- true
+               time.Sleep(2 * time.Second)
+       }
+
+       if readErr != nil {
+               return readErr
+       }
+
+       // post subscription req to appmgr
+       readErr = PostSubReq(xmurl, nbiif)
+       if readErr != nil {
+               return readErr
+       }
+
+       //rlist := make(map[string]string)
+       xapp.Logger.Info("Reading SDL for any routes")
+       rlist, sdlerr := xapp.Sdl.Read("routes")
+       readErr = sdlerr
+       if readErr == nil {
+               xapp.Logger.Info("Value is %s", rlist["routes"])
+               if rlist["routes"] != nil {
+                       formstring := fmt.Sprintf("%s", rlist["routes"])
+                       xapp.Logger.Info("Value of formed string = %s", formstring)
+                       newstring := strings.Split(formstring, " ")
+                       for i, _ := range newstring {
+                               xapp.Logger.Info("in Loop Value of formed string = %s", newstring)
+                               rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, newstring[i])
+                       }
                }
                }
-       }()
+
+               return nil
+       }
+
+       return readErr
+}
+
+func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string, e2murl string,
+       sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) error {
+       err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, e2murl, sdlEngine)
+       if err != nil {
+               xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
+               return err
+       }
 
        return nil
 }
 
        return nil
 }
@@ -341,11 +612,12 @@ func (r *HttpRestful) Terminate() error {
 }
 
 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
 }
 
 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
+       xapp.Logger.Debug("Adding the subscription into the subscriptions list")
        var b = false
        sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
        for _, elem := range *subs {
                if elem == sub {
        var b = false
        sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
        for _, elem := range *subs {
                if elem == sub {
-                       rtmgr.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
+                       xapp.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
                        b = true
                }
        }
                        b = true
                }
        }
@@ -356,7 +628,7 @@ func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubsc
 }
 
 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
 }
 
 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
-       rtmgr.Logger.Debug("Deleteing the subscription from the subscriptions list")
+       xapp.Logger.Debug("Deleteing the subscription from the subscriptions list")
        var present = false
        sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
        for i, elem := range *subs {
        var present = false
        sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
        for i, elem := range *subs {
@@ -370,7 +642,115 @@ func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubsc
                }
        }
        if present == false {
                }
        }
        if present == false {
-               rtmgr.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
+               xapp.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
        }
        return present
 }
        }
        return present
 }
+
+func updateSubscription(data *rtmgr.XappList) {
+
+       var subdata models.XappSubscriptionData
+       var id int32
+       var matchingsubid, deletecount uint8
+       id = int32(data.SubscriptionID)
+       subdata.SubscriptionID = &id
+       for _, subs := range rtmgr.Subs {
+               if int32(data.SubscriptionID) == subs.SubID {
+                       matchingsubid++
+               }
+       }
+
+       for deletecount < matchingsubid {
+               for _, subs := range rtmgr.Subs {
+                       if int32(data.SubscriptionID) == subs.SubID {
+                               subdata.SubscriptionID = &subs.SubID
+                               subdata.Address = &subs.Fqdn
+                               subdata.Port = &subs.Port
+                               xapp.Logger.Debug("Deletion Subscription List has %v", subdata)
+                               delSubscription(&rtmgr.Subs, &subdata)
+                               break
+                       }
+               }
+               deletecount++
+       }
+
+       for _, items := range data.FqdnList {
+               subdata.Address = items.Address
+               subdata.Port = items.Port
+               xapp.Logger.Debug("Adding Subscription List has %v", subdata)
+               addSubscription(&rtmgr.Subs, &subdata)
+       }
+
+}
+
+func PopulateSubscription(sub_list xfmodel.SubscriptionList) {
+       for _, sub_row := range sub_list {
+               var subdata models.XappSubscriptionData
+               id := int32(sub_row.SubscriptionID)
+               subdata.SubscriptionID = &id
+               for _, ep := range sub_row.Endpoint {
+
+                       stringSlice := strings.Split(ep, ":")
+                       subdata.Address = &stringSlice[0]
+                       intportval, _ := strconv.Atoi(stringSlice[1])
+                       value := uint16(intportval)
+                       subdata.Port = &value
+                       xapp.Logger.Debug("Adding Subscription List has Address :%v, port :%v, SubscriptionID :%v ", subdata.Address, subdata.Address, subdata.SubscriptionID)
+                       addSubscription(&rtmgr.Subs, &subdata)
+               }
+       }
+}
+
+func Adddelrmrroute(routelist models.Routelist, rtflag bool) error {
+       xapp.Logger.Info("Updating rmrroute with Route list: %v,flag: %v", routelist, rtflag)
+       for _, rlist := range routelist {
+               var subid int32
+               var data string
+               if rlist.SubscriptionID == 0 {
+                       subid = -1
+               } else {
+                       subid = rlist.SubscriptionID
+               }
+               if rlist.SenderEndPoint == "" && rlist.SubscriptionID != 0 {
+                       data = fmt.Sprintf("mse|%d|%d|%s\n", *rlist.MessageType, rlist.SubscriptionID, *rlist.TargetEndPoint)
+               } else if rlist.SenderEndPoint == "" && rlist.SubscriptionID == 0 {
+                       data = fmt.Sprintf("mse|%d|-1|%s\n", *rlist.MessageType, *rlist.TargetEndPoint)
+               } else {
+                       data = fmt.Sprintf("mse|%d,%s|%d|%s\n", *rlist.MessageType, rlist.SenderEndPoint, subid, *rlist.TargetEndPoint)
+               }
+               err := checkrepeatedroute(data)
+
+               if rtflag == true {
+                       if err == true {
+                               xapp.Logger.Info("Given route %s is a duplicate", data)
+                       }
+                       rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, data)
+                       routearray := strings.Join(rtmgr.DynamicRouteList, " ")
+                       xapp.Sdl.Store("routes", routearray)
+               } else {
+                       if err == true {
+                               xapp.Logger.Info("Successfully deleted route: %s", data)
+                               routearray := strings.Join(rtmgr.DynamicRouteList, " ")
+                               xapp.Sdl.Store("routes", routearray)
+                       } else {
+                               xapp.Logger.Info("No such route: %s", data)
+                               return errors.New("No such route: " + data)
+                       }
+
+               }
+       }
+       updateEp()
+       return sendRoutesToAll()
+}
+
+func checkrepeatedroute(data string) bool {
+       for i := 0; i < len(rtmgr.DynamicRouteList); i++ {
+               if rtmgr.DynamicRouteList[i] == data {
+                       rtmgr.DynamicRouteList[i] = rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1]
+                       rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1] = ""
+                       rtmgr.DynamicRouteList = rtmgr.DynamicRouteList[:len(rtmgr.DynamicRouteList)-1]
+                       return true
+               }
+       }
+       return false
+}