Multiple E2T instance feature - Introduced APIs Delete E2T Instance and associate RANs to E2T & disassociate RANs from E2T Instance

Change-Id: Ic3380caee22e53daf46ffc8a26a828003d218f3b
Signed-off-by: prabhukaliswamy <prabhu.k@nokia.com>
diff --git a/pkg/nbi/httpgetter.go b/pkg/nbi/httpgetter.go
index fca48f4..5d7b818 100644
--- a/pkg/nbi/httpgetter.go
+++ b/pkg/nbi/httpgetter.go
@@ -38,6 +38,7 @@
 	"routing-manager/pkg/rtmgr"
 	"routing-manager/pkg/sdl"
 	"time"
+	"sync"
 )
 
 type HttpGetter struct {
@@ -77,7 +78,7 @@
 }
 
 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
 }
 
diff --git a/pkg/nbi/httprestful.go b/pkg/nbi/httprestful.go
index 5e90bfa..2e14690 100644
--- a/pkg/nbi/httprestful.go
+++ b/pkg/nbi/httprestful.go
@@ -49,6 +49,8 @@
 	"routing-manager/pkg/sdl"
 	"strconv"
 	"time"
+	"sync"
+	"strings"
 )
 
 //var myClient = &http.Client{Timeout: 1 * time.Second}
@@ -57,8 +59,7 @@
 	Engine
 	LaunchRest                   LaunchRestHandler
 	RecvXappCallbackData         RecvXappCallbackDataHandler
-        RecvNewE2Tdata               RecvNewE2TdataHandler
-
+        RecvNewE2Tdata               RecvNewE2TdataHandler 
 	ProvideXappHandleHandlerImpl ProvideXappHandleHandlerImpl
 	RetrieveStartupData          RetrieveStartupDataHandler
 }
@@ -104,10 +105,17 @@
         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 @@
         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 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 @@
                 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 @@
                         }
                 })
 
+       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 (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 @@
 	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 @@
 				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 @@
                 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
                         }
                 }
diff --git a/pkg/nbi/httprestful_test.go b/pkg/nbi/httprestful_test.go
index cfa644e..465f17b 100644
--- a/pkg/nbi/httprestful_test.go
+++ b/pkg/nbi/httprestful_test.go
@@ -44,6 +44,7 @@
 	"routing-manager/pkg/stub"
 	"testing"
 	"time"
+	"sync"
 
 	"github.com/go-openapi/swag"
 )
@@ -172,7 +173,8 @@
 	//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) {
diff --git a/pkg/nbi/types.go b/pkg/nbi/types.go
index 78f99a5..085486c 100644
--- a/pkg/nbi/types.go
+++ b/pkg/nbi/types.go
@@ -34,12 +34,13 @@
 	"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 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
 }
diff --git a/pkg/rpe/rmr.go b/pkg/rpe/rmr.go
index 6fc8c9f..80323a3 100644
--- a/pkg/rpe/rmr.go
+++ b/pkg/rpe/rmr.go
@@ -34,6 +34,7 @@
 	"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 @@
 /*
 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 @@
 		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 {
diff --git a/pkg/rpe/rmr_test.go b/pkg/rpe/rmr_test.go
index 4538d97..da8da06 100644
--- a/pkg/rpe/rmr_test.go
+++ b/pkg/rpe/rmr_test.go
@@ -47,11 +47,12 @@
 */
 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)
 }
 
diff --git a/pkg/rpe/rpe.go b/pkg/rpe/rpe.go
index 9a963c7..11440db 100644
--- a/pkg/rpe/rpe.go
+++ b/pkg/rpe/rpe.go
@@ -163,10 +163,13 @@
 		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 {
diff --git a/pkg/rpe/types.go b/pkg/rpe/types.go
index 626213e..4a5b9fc 100644
--- a/pkg/rpe/types.go
+++ b/pkg/rpe/types.go
@@ -43,6 +43,6 @@
 }
 
 type Engine interface {
-	GeneratePolicies(rtmgr.Endpoints) *[]string
+	GeneratePolicies(rtmgr.Endpoints, *rtmgr.RicComponents) *[]string
 	GenerateRouteTable(rtmgr.Endpoints) *rtmgr.RouteTable
 }
diff --git a/pkg/sdl/file.go b/pkg/sdl/file.go
index b4f1e8e..969f7bd 100644
--- a/pkg/sdl/file.go
+++ b/pkg/sdl/file.go
@@ -35,6 +35,7 @@
 	"io/ioutil"
 	"os"
 	"routing-manager/pkg/rtmgr"
+	"routing-manager/pkg/models"
 )
 
 /*
@@ -60,11 +61,11 @@
 		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 @@
         }
         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
+}
diff --git a/pkg/sdl/types.go b/pkg/sdl/types.go
index f94557e..f4a9125 100644
--- a/pkg/sdl/types.go
+++ b/pkg/sdl/types.go
@@ -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 @@
 	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
 }