Create E2T API implementation and yaml change for multiple e2t instances handling... 85/1985/2
authorrangajal <ranjit.angajala@nokia.com>
Tue, 10 Dec 2019 09:37:08 +0000 (09:37 +0000)
committerrangajal <ranjit.angajala@nokia.com>
Tue, 10 Dec 2019 11:33:31 +0000 (11:33 +0000)
Change-Id: I22cbd45c54aa0072159b9c2f041355d5ddc51b69
Signed-off-by: rangajal <ranjit.angajala@nokia.com>
12 files changed:
RELNOTES
api/routing_manager.yaml
container-tag.yaml
pkg/nbi/httprestful.go
pkg/nbi/types.go
pkg/rpe/rmr.go
pkg/rpe/rpe.go
pkg/rtmgr/rtmgr.go
pkg/rtmgr/types.go
pkg/sbi/sbi.go
pkg/sdl/file.go
pkg/sdl/types.go

index a5fb036..20b981c 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,3 +1,6 @@
+### v0.4.4
+* Create E2T Instance API introduced for Multiple E2T Feature
+
 ### v0.4.3
 * Included RMR changes that has MEID implementation
 
index f4f852d..c2dacfa 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.
-#
-#   This source code is part of the near-RT RIC (RAN Intelligent Controller)
-#   platform project (RICP).
-#
 #==================================================================================
 #
 #
-#
 #   Abstract:   Routing Manager's RESTful API definition
 #   Date:       28 August 2019
 #
@@ -182,7 +177,105 @@ paths:
           description: "Invalid data"
         201:
           description: "Xapp list received"
-  
+  /handles/v1/e2t:
+    post:
+      tags:
+      - "handle"
+      summary: "API for establishing platform routes when a new e2t instance gets added to platform"
+      description: "E2T updates its FQDN to E2M  during its initialisation, hence after E2M informs routing manager about new E2T instances FQDN. At this point Routing Mgr would establish platform routes"
+      operationId: "create_new_e2t_handle"
+      consumes:
+      - "application/json"
+#      - "application/yaml"
+      produces:
+      - "application/json"
+#      - "application/yaml"
+      parameters:
+        - in: body
+          name: e2t-data
+          description: "FQDN of the newly joined E2T instance"
+          required: true
+          schema:
+           $ref: "#/definitions/e2t-data"
+      responses:
+        400:
+          description: "Invalid data"
+        201:
+          description: "new e2t instance is considered and platform routes are established"
+    delete:
+      tags:
+      - "handle"
+      summary: "API for clearing routes specific to a particular e2T instance"
+      description: "E2M would monitor E2T instances using its keep alive based mechanism during this time if an E2T instance is detected to be dead, E2M would distribute already associated ran's to other available/healthy E2T instances. Here E2M would share E2T instance address to be removed OR which is unhealthy and list of RAN instances to be dissociated and an association list which contains E2T FQDN and associated RAN names"
+      operationId: "delete_e2t_handle"
+      consumes:
+      - "application/json"
+#      - "application/yaml"
+      produces:
+      - "application/json"
+#      - "application/yaml"
+      parameters:
+        - in: body
+          name: e2t-data
+          description: "FQDN of the newly joined E2T instance"
+          required: true
+          schema:
+           $ref: "#/definitions/e2t-delete-data"
+      responses:
+        400:
+          description: "Invalid data"
+        201:
+          description: "new e2t instance is considered and platform routes are established"
+  /handles/v1/associate-ran-to-e2t:
+    post:
+      tags:
+      - "handle"
+      summary: "API for associating a ran to e2t instance"
+      description: "By performing a POST method on rane2tmapping, the API caller is able to update the Routing manager about the ran to e2t mapping which would be finally used to distribute routes to corresponding xApp and E2T instance"
+      operationId: "associate_ran_to_e2t_handle"
+      consumes:
+      - "application/json"
+#      - "application/yaml"
+      produces:
+      - "application/json"
+#      - "application/yaml"
+      parameters:
+        - in: body
+          name: ran-e2t-list
+          description: "ran to e2t mapping"
+          required: true
+          schema:
+           $ref: "#/definitions/ran-e2t-map"
+      responses:
+        400:
+          description: "Invalid data"
+        201:
+          description: "e2t ran mapping recieved, platform routes"
+  /handles/v1/dissociate-ran:
+    post:
+      tags:
+      - "handle"
+      summary: "API to dissociate ran from e2t"
+      description: "By performing a POST method on rane2tmapping, routing manager will dissociate ran name from e2t instance by updating or clearing routes"
+      operationId: "dissociate_ran"
+      consumes:
+      - "application/json"
+#      - "application/yaml"
+      produces:
+      - "application/json"
+#      - "application/yaml"
+      parameters:
+        - in: body
+          name: dissociate-list
+          description: "list of RAN to dissociate"
+          required: true
+          schema:
+           $ref: "#/definitions/ran-e2t-map"
+      responses:
+        400:
+          description: "Invalid data"
+        201:
+          description: "ran instances disociated"
 definitions:
   health-status:
     type: "object"
@@ -238,6 +331,44 @@ definitions:
         format: "uint16"
         minimum: 0
         maximum: 65535
+  ran-e2t-map:
+    type: "array"
+    items:
+      $ref: '#/definitions/ran-e2t-element'
+  ran-e2t-element:
+    type: "object"
+    required:
+      - "E2TAddress"
+    properties:
+      E2TAddress:
+        type: "string" #This is the ideally E2T FQDN or IP:PORT
+      ranNamelist: #list of RAN Names
+        $ref: '#/definitions/ranNamelist'
+  ranNamelist:
+    type: "array"
+    items:
+      type: "string" #This could be FQDN or this needs to be an object?
+  e2t-data:
+    type: "object"
+    required:
+      - "E2TAddress"
+    properties:
+      E2TAddress:
+        type: "string" #This is FQDN or IP of E2T instance
+      ranNamelist:
+        $ref: '#/definitions/ranNamelist'
+  e2t-delete-data:
+    type: "object"
+    required:
+      - "E2TAddress"
+    properties:
+      E2TAddress:
+        type: "string" #This E2T instances FQDN or 
+      ranNamelistTobeDissociated: #xapp instance port address
+        $ref: '#/definitions/ranNamelist'
+      ranAssocList:
+        $ref: "#/definitions/ran-e2t-map"
+          
 
 externalDocs:
   description: "Routing Manager"
index 2af355a..cfdbfb8 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.3
+tag: 0.4.4
index db8129e..5e90bfa 100644 (file)
@@ -57,6 +57,8 @@ type HttpRestful struct {
        Engine
        LaunchRest                   LaunchRestHandler
        RecvXappCallbackData         RecvXappCallbackDataHandler
+        RecvNewE2Tdata               RecvNewE2TdataHandler
+
        ProvideXappHandleHandlerImpl ProvideXappHandleHandlerImpl
        RetrieveStartupData          RetrieveStartupDataHandler
 }
@@ -65,6 +67,7 @@ func NewHttpRestful() *HttpRestful {
        instance := new(HttpRestful)
        instance.LaunchRest = launchRest
        instance.RecvXappCallbackData = recvXappCallbackData
+        instance.RecvNewE2Tdata = recvNewE2Tdata
        instance.ProvideXappHandleHandlerImpl = provideXappHandleHandlerImpl
        instance.RetrieveStartupData = retrieveStartupData
        return instance
@@ -94,6 +97,28 @@ func recvXappCallbackData(dataChannel <-chan *models.XappCallbackData) (*[]rtmgr
        return nil, nil
 }
 
+func recvNewE2Tdata(dataChannel <-chan *models.E2tData) (*rtmgr.E2TInstance, error) {
+        var e2tData *models.E2tData
+        xapp.Logger.Info("data received")
+
+        e2tData = <-dataChannel
+
+        if nil != e2tData {
+                var e2tinst rtmgr.E2TInstance
+                e2tinst.Fqdn = *e2tData.E2TAddress
+                e2tinst.Name = "E2TERMINST"
+                return &e2tinst,nil
+        } else {
+                xapp.Logger.Info("No data")
+        }
+
+        xapp.Logger.Debug("Nothing received on the Http interface")
+        return nil, nil
+}
+
+
+
+
 func validateXappCallbackData(callbackData *models.XappCallbackData) error {
        if len(callbackData.XApps) == 0 {
                return fmt.Errorf("invalid Data field: \"%s\"", callbackData.XApps)
@@ -131,6 +156,21 @@ func validateXappSubscriptionData(data *models.XappSubscriptionData) error {
        return err
 }
 
+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
+        }
+        return err
+}
+
 func provideXappSubscriptionHandleImpl(subchan chan<- *models.XappSubscriptionData,
        data *models.XappSubscriptionData) error {
        xapp.Logger.Debug("Invoked provideXappSubscriptionHandleImpl")
@@ -176,8 +216,21 @@ func deleteXappSubscriptionHandleImpl(subdelchan chan<- *models.XappSubscription
        return nil
 }
 
+func createNewE2tHandleHandlerImpl(e2taddchan chan<- *models.E2tData,
+        data *models.E2tData) error {
+        xapp.Logger.Debug("Invoked createNewE2tHandleHandlerImpl")
+        err := validateE2tData(data)
+        if err != nil {
+                xapp.Logger.Error(err.Error())
+                return err
+        }
+
+        e2taddchan <- data
+        return nil
+}
+
 func launchRest(nbiif *string, datach chan<- *models.XappCallbackData, subchan chan<- *models.XappSubscriptionData,
-       subdelchan chan<- *models.XappSubscriptionData) {
+       subdelchan chan<- *models.XappSubscriptionData, e2taddchan chan<- *models.E2tData) {
        swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
        if err != nil {
                //log.Fatalln(err)
@@ -233,6 +286,17 @@ func launchRest(nbiif *string, datach chan<- *models.XappCallbackData, subchan c
                                return handle.NewGetHandlesOK()
                        }
                })
+       api.HandleCreateNewE2tHandleHandler = handle.CreateNewE2tHandleHandlerFunc(
+                func(params handle.CreateNewE2tHandleParams) middleware.Responder {
+                        err := createNewE2tHandleHandlerImpl(e2taddchan, params.E2tData)
+                        if err != nil {
+                                return handle.NewCreateNewE2tHandleBadRequest()
+                        } else {
+                               time.Sleep(1 * time.Second)
+                                return handle.NewCreateNewE2tHandleCreated()
+                        }
+                })
+
        // start to serve API
        xapp.Logger.Info("Starting the HTTP Rest service")
        if err := server.Serve(); err != nil {
@@ -277,7 +341,7 @@ func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile
                        }
                        xapp.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}
+                       ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts:  make(map[string]rtmgr.E2TInstance)}
                        writeErr := sdlEngine.WriteAll(fileName, ricData)
                        if writeErr != nil {
                                xapp.Logger.Error(writeErr.Error())
@@ -308,9 +372,10 @@ func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, co
        datach := make(chan *models.XappCallbackData, 10)
        subschan := make(chan *models.XappSubscriptionData, 10)
        subdelchan := make(chan *models.XappSubscriptionData, 10)
+       e2taddchan := make(chan *models.E2tData, 10)
        xapp.Logger.Info("Launching Rest Http service")
        go func() {
-               r.LaunchRest(&nbiif, datach, subschan, subdelchan)
+               r.LaunchRest(&nbiif, datach, subschan, subdelchan, e2taddchan)
        }()
 
        go func() {
@@ -347,6 +412,20 @@ func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, co
                }
        }()
 
+        go func() {
+                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 {
+                                sdlEngine.WriteNewE2TInstance(fileName, data)
+                                triggerSBI <- true
+                        }
+                }
+        }()
+
        return nil
 }
 
index dd184d2..78f99a5 100644 (file)
@@ -38,7 +38,8 @@ import (
 
 type FetchAllXAppsHandler func(string) (*[]rtmgr.XApp, error)
 type RecvXappCallbackDataHandler func(<-chan *models.XappCallbackData) (*[]rtmgr.XApp, error)
-type LaunchRestHandler func(*string, chan<- *models.XappCallbackData, chan<- *models.XappSubscriptionData, chan<- *models.XappSubscriptionData)
+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 ProvideXappHandleHandlerImpl func(chan<- *models.XappCallbackData, *models.XappCallbackData) error
 type RetrieveStartupDataHandler func(string, string, string, string, sdl.Engine) error
 
index 8929c63..6fc8c9f 100644 (file)
@@ -78,9 +78,19 @@ func (r *Rmr) generateRMRPolicies(eps rtmgr.Endpoints, key string) *[]string {
                        }
                }
                rawrte += group
+
+                if (rte.RouteType == "%meid") {
+                        rawrte += group + rte.RouteType
+                }
+
                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")
+
        xapp.Logger.Debug("rmr.GeneratePolicies returns: %v", rawrt)
        return &rawrt
 }
index 35006c8..9a963c7 100644 (file)
@@ -73,6 +73,19 @@ func getEndpointByName(eps *rtmgr.Endpoints, name string) *rtmgr.Endpoint {
        return nil
 }
 
+func getEndpointListByName(eps *rtmgr.Endpoints, name string) []rtmgr.Endpoint {
+        var eplist []rtmgr.Endpoint
+
+        for _, ep := range *eps {
+                if ep.Name == name {
+                        xapp.Logger.Debug("name: %s", ep.Name)
+                        xapp.Logger.Debug("ep: %v", ep)
+                        eplist = append(eplist, *ep)
+                }
+        }
+        return eplist
+}
+
 func getEndpointByUuid(uuid string) *rtmgr.Endpoint {
        endPoints := rtmgr.Eps
        for _, ep := range endPoints {
@@ -85,48 +98,81 @@ func getEndpointByUuid(uuid string) *rtmgr.Endpoint {
        return nil
 }
 
-func (r *Rpe) addRoute(messageType string, tx *rtmgr.Endpoint, rx *rtmgr.Endpoint, routeTable *rtmgr.RouteTable, subId int32) {
-       var txList rtmgr.EndpointList
-       if rx != nil {
-               rxList := []rtmgr.EndpointList{[]rtmgr.Endpoint{*rx}}
-               if tx != nil {
-                       txList = rtmgr.EndpointList{*tx}
+func (r *Rpe) addRoute(messageType string, tx *rtmgr.Endpoint, rx *rtmgr.Endpoint, routeTable *rtmgr.RouteTable, subId int32, routeType string) {
+       txList := rtmgr.EndpointList{}
+       rxList := []rtmgr.EndpointList{}
+
+       if tx == nil && rx == nil {
+               pc, _, _, ok := runtime.Caller(1)
+               details := runtime.FuncForPC(pc)
+               if ok && details != nil {
+                       xapp.Logger.Error("Route addition skipped: Either TX or RX endpoint not present. Caller function is %s", details.Name())
                }
-               messageId := rtmgr.MessageTypes[messageType]
-               route := rtmgr.RouteTableEntry{
-                       MessageType: messageId,
-                       TxList:      txList,
-                       RxGroups:    rxList,
-                       SubID:       subId}
-               *routeTable = append(*routeTable, route)
-               xapp.Logger.Debug("Route added: MessageTyp: %v,  Rx: %v, SubId: %v", messageId, rx.Uuid, subId)
        } else {
-               pc, _, _, ok := runtime.Caller(1)
-               details := runtime.FuncForPC(pc)
-               if ok && details != nil {
-                       xapp.Logger.Error("Route addition skipped: Either TX or RX endpoint not present. Caller function is %s", details.Name())
-               }
+               if (tx != nil) {
+                       txList = rtmgr.EndpointList{*tx}
+               }
+               if (rx != nil) {
+                       rxList = []rtmgr.EndpointList{[]rtmgr.Endpoint{*rx}}
+               }
+               messageId := rtmgr.MessageTypes[messageType]
+               route := rtmgr.RouteTableEntry{
+                       MessageType: messageId,
+                       TxList:      txList,
+                       RxGroups:    rxList,
+                       SubID:       subId,
+                       RouteType:   routeType}
+               *routeTable = append(*routeTable, route)
+//             xapp.Logger.Debug("Route added: MessageTyp: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx.Uuid, rx.Uuid, subId)
+//             xapp.Logger.Trace("Route added: MessageTyp: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx, rx, subId)
+       }
+}
+
+func (r *Rpe) addRoute_rx_list(messageType string, tx *rtmgr.Endpoint, rx []rtmgr.Endpoint, routeTable *rtmgr.RouteTable, subId int32, routeType string) {
+       txList := rtmgr.EndpointList{}
+       rxList := []rtmgr.EndpointList{}
+
+       if (tx != nil) {
+               txList = rtmgr.EndpointList{*tx}
        }
+
+       if (rx != nil) {
+               rxList = []rtmgr.EndpointList{rx}
+       }
+
+       messageId := rtmgr.MessageTypes[messageType]
+       route := rtmgr.RouteTableEntry{
+               MessageType: messageId,
+               TxList:      txList,
+               RxGroups:    rxList,
+               SubID:       subId,
+               RouteType:   routeType}
+       *routeTable = append(*routeTable, route)
+//     xapp.Logger.Debug("Route added: MessageTyp: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx.Uuid, rx.Uuid, subId)
+//     xapp.Logger.Trace("Route added: MessageTyp: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx, rx, subId)
 }
 
+
+
 func (r *Rpe) generateXappRoutes(xAppEp *rtmgr.Endpoint, e2TermEp *rtmgr.Endpoint, subManEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
        xapp.Logger.Debug("rpe.generateXappRoutes invoked")
        xapp.Logger.Debug("Endpoint: %v, xAppType: %v", xAppEp.Name, xAppEp.XAppType)
        if xAppEp.XAppType != sbi.PlatformType && (len(xAppEp.TxMessages) > 0 || len(xAppEp.RxMessages) > 0) {
+               /// TODO --- 
                //xApp -> Subscription Manager
-               r.addRoute("RIC_SUB_REQ", xAppEp, subManEp, routeTable, -1)
-               r.addRoute("RIC_SUB_DEL_REQ", xAppEp, subManEp, routeTable, -1)
+               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, "")
                //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, "")
        }
        //xApp->A1Mediator
        if xAppEp.XAppType != sbi.PlatformType && len(xAppEp.Policies) > 0 {
                xapp.Logger.Debug("rpe.generateXappRoutes found policies section")
                for _, policy := range xAppEp.Policies {
-                       r.addRoute("A1_POLICY_REQ", nil, xAppEp, routeTable, policy)
+                       r.addRoute("A1_POLICY_REQ", nil, xAppEp, routeTable, policy, "")
                }
        }
 
@@ -142,30 +188,32 @@ func (r *Rpe) generateSubscriptionRoutes(selectedxAppEp *rtmgr.Endpoint, e2TermE
                xAppEp := getEndpointByUuid(xAppUuid)
                if xAppEp.Uuid == selectedxAppEp.Uuid {
                        xapp.Logger.Debug("xApp UUID is matched for selected xApp.UUID: %v and xApp.Name: %v", selectedxAppEp.Uuid, selectedxAppEp.Name)
+/// TODO
                        //Subscription Manager -> xApp
-                       r.addRoute("RIC_SUB_RESP", subManEp, xAppEp, routeTable, subscription.SubID)
-                       r.addRoute("RIC_SUB_FAILURE", subManEp, xAppEp, routeTable, subscription.SubID)
-                       r.addRoute("RIC_SUB_DEL_RESP", subManEp, xAppEp, routeTable, subscription.SubID)
-                       r.addRoute("RIC_SUB_DEL_FAILURE", subManEp, xAppEp, routeTable, subscription.SubID)
+                       r.addRoute("RIC_SUB_RESP", subManEp, xAppEp, routeTable, subscription.SubID, "")
+                       r.addRoute("RIC_SUB_FAILURE", subManEp, xAppEp, routeTable, subscription.SubID, "")
+                       r.addRoute("RIC_SUB_DEL_RESP", subManEp, xAppEp, routeTable, subscription.SubID, "")
+                       r.addRoute("RIC_SUB_DEL_FAILURE", subManEp, xAppEp, routeTable, subscription.SubID, "")
                        //E2 Termination -> xApp
-                       r.addRoute("RIC_INDICATION", e2TermEp, xAppEp, routeTable, subscription.SubID)
-                       r.addRoute("RIC_CONTROL_ACK", e2TermEp, xAppEp, routeTable, subscription.SubID)
-                       r.addRoute("RIC_CONTROL_FAILURE", e2TermEp, xAppEp, routeTable, subscription.SubID)
+                       r.addRoute("RIC_INDICATION", e2TermEp, xAppEp, routeTable, subscription.SubID, "")
+                       r.addRoute("RIC_CONTROL_ACK", e2TermEp, xAppEp, routeTable, subscription.SubID, "")
+                       r.addRoute("RIC_CONTROL_FAILURE", e2TermEp, xAppEp, routeTable, subscription.SubID, "")
                }
        }
 }
 
-func (r *Rpe) generatePlatformRoutes(e2TermEp *rtmgr.Endpoint, subManEp *rtmgr.Endpoint, e2ManEp *rtmgr.Endpoint, ueManEp *rtmgr.Endpoint, rsmEp *rtmgr.Endpoint, a1mediatorEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
+func (r *Rpe) generatePlatformRoutes(e2TermEp []rtmgr.Endpoint, subManEp *rtmgr.Endpoint, e2ManEp *rtmgr.Endpoint, ueManEp *rtmgr.Endpoint, rsmEp *rtmgr.Endpoint, a1mediatorEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
        xapp.Logger.Debug("rpe.generatePlatformRoutes invoked")
        //Platform Routes --- Subscription Routes
        //Subscription Manager -> E2 Termination
-       r.addRoute("RIC_SUB_REQ", subManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_SUB_DEL_REQ", subManEp, e2TermEp, routeTable, -1)
+       r.addRoute("RIC_SUB_REQ", subManEp, nil, routeTable, -1, "%meid")
+       r.addRoute("RIC_SUB_DEL_REQ", subManEp, nil, routeTable, -1, "%meid")
        //E2 Termination -> Subscription Manager
-       r.addRoute("RIC_SUB_RESP", e2TermEp, subManEp, routeTable, -1)
-       r.addRoute("RIC_SUB_DEL_RESP", e2TermEp, subManEp, routeTable, -1)
-       r.addRoute("RIC_SUB_FAILURE", e2TermEp, subManEp, routeTable, -1)
-       r.addRoute("RIC_SUB_DEL_FAILURE", e2TermEp, subManEp, routeTable, -1)
+        r.addRoute("RIC_SUB_RESP", nil, subManEp, routeTable, -1, "")
+        r.addRoute("RIC_SUB_DEL_RESP", nil, subManEp, routeTable, -1, "")
+        r.addRoute("RIC_SUB_FAILURE", nil, subManEp, routeTable, -1, "")
+        r.addRoute("RIC_SUB_DEL_FAILURE", nil, subManEp, routeTable, -1, "")
+
        //TODO: UE Man Routes removed (since it is not existing)
        //UE Manager -> Subscription Manager
        //r.addRoute("RIC_SUB_REQ", ueManEp, subManEp, routeTable)
@@ -175,40 +223,51 @@ func (r *Rpe) generatePlatformRoutes(e2TermEp *rtmgr.Endpoint, subManEp *rtmgr.E
 
        //Platform Routes --- X2 Routes
        //E2 Manager -> E2 Termination
-       r.addRoute("RIC_X2_SETUP_REQ", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_X2_RESET_REQ", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_X2_RESET_RESP", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_ENDC_X2_SETUP_REQ", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_ENB_CONF_UPDATE_ACK", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_ENB_CONF_UPDATE_FAILURE", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_ENDC_CONF_UPDATE_ACK", e2ManEp, e2TermEp, routeTable, -1)
-       r.addRoute("RIC_ENDC_CONF_UPDATE_FAILURE", e2ManEp, e2TermEp, routeTable, -1)
+        r.addRoute("RIC_X2_SETUP_REQ", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_X2_RESET_REQ", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_X2_RESET_RESP", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_ENDC_X2_SETUP_REQ", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_ENB_CONF_UPDATE_ACK", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_ENB_CONF_UPDATE_FAILURE", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_ENDC_CONF_UPDATE_ACK", e2ManEp, nil, routeTable, -1, "%meid")
+        r.addRoute("RIC_ENDC_CONF_UPDATE_FAILURE", e2ManEp, nil, routeTable, -1, "%meid")
+
+        if len(e2TermEp) > 0 {
+                r.addRoute_rx_list("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermEp, routeTable, -1, "")
+                r.addRoute_rx_list("E2_TERM_KEEP_ALIVE_REQ", e2ManEp, e2TermEp, routeTable, -1, "")
+        }
+
        //E2 Termination -> E2 Manager
-       r.addRoute("E2_TERM_INIT", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_X2_SETUP_RESP", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_X2_SETUP_FAILURE", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_X2_RESET_REQ", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_X2_RESET_RESP", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_ENDC_X2_SETUP_RESP", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_ENDC_X2_SETUP_FAILURE", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_ENDC_CONF_UPDATE", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_SCTP_CONNECTION_FAILURE", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_ERROR_INDICATION", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_ENB_CONF_UPDATE", e2TermEp, e2ManEp, routeTable, -1)
-       r.addRoute("RIC_ENB_LOAD_INFORMATION", e2TermEp, e2ManEp, routeTable, -1)
+        r.addRoute("E2_TERM_INIT", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_X2_SETUP_RESP", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_X2_SETUP_FAILURE", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_X2_RESET_REQ", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_X2_RESET_RESP", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_ENDC_X2_SETUP_RESP", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_ENDC_X2_SETUP_FAILURE", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_ENDC_CONF_UPDATE", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_SCTP_CONNECTION_FAILURE", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_ERROR_INDICATION", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_ENB_CONF_UPDATE", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("RIC_ENB_LOAD_INFORMATION", nil, e2ManEp, routeTable, -1, "")
+        r.addRoute("E2_TERM_KEEP_ALIVE_RESP", nil, e2ManEp, routeTable, -1, "")
+
+
+
        //E2 Manager -> Resource Status Manager
-       r.addRoute("RAN_CONNECTED", e2ManEp, rsmEp, routeTable, -1)
-       r.addRoute("RAN_RESTARTED", e2ManEp, rsmEp, routeTable, -1)
-       r.addRoute("RAN_RECONFIGURED", e2ManEp, rsmEp, routeTable, -1)
+        r.addRoute("RAN_CONNECTED", e2ManEp, rsmEp, routeTable, -1, "")
+        r.addRoute("RAN_RESTARTED", e2ManEp, rsmEp, routeTable, -1, "")
+        r.addRoute("RAN_RECONFIGURED", e2ManEp, rsmEp, routeTable, -1, "")
+
        //Resource Status Manager -> E2 Termination
-       r.addRoute("RIC_RES_STATUS_REQ", rsmEp, e2TermEp, routeTable, -1)
+       r.addRoute("RIC_RES_STATUS_REQ", rsmEp, nil, routeTable, -1, "%meid")
        //E2 Termination -> Resource Status Manager
-       r.addRoute("RIC_RES_STATUS_RESP", e2TermEp, rsmEp, routeTable, -1)
-       r.addRoute("RIC_RES_STATUS_FAILURE", e2TermEp, rsmEp, routeTable, -1)
+        r.addRoute("RIC_RES_STATUS_RESP", nil, rsmEp, routeTable, -1, "")
+        r.addRoute("RIC_RES_STATUS_FAILURE", nil, rsmEp, routeTable, -1, "")
+
        //ACxapp -> A1 Mediator
-       r.addRoute("A1_POLICY_QUERY", nil, a1mediatorEp, routeTable, -1)
-       r.addRoute("A1_POLICY_RESPONSE", nil, a1mediatorEp, routeTable, -1)
+       r.addRoute("A1_POLICY_QUERY", nil, a1mediatorEp, routeTable, -1, "")
+       r.addRoute("A1_POLICY_RESPONSE", nil, a1mediatorEp, routeTable, -1, "")
 }
 
 func (r *Rpe) generateRouteTable(endPointList rtmgr.Endpoints) *rtmgr.RouteTable {
@@ -246,7 +305,12 @@ func (r *Rpe) generateRouteTable(endPointList rtmgr.Endpoints) *rtmgr.RouteTable
                xapp.Logger.Debug("Endpoints: %v", endPointList)
        }
 
-       r.generatePlatformRoutes(e2TermEp, subManEp, e2ManEp, ueManEp, rsmEp, A1MediatorEp, routeTable)
+       e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
+       if len(e2TermListEp) == 0 {
+               xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
+               xapp.Logger.Debug("Endpoints: %v", endPointList)
+       }
+       r.generatePlatformRoutes(e2TermListEp, subManEp, e2ManEp, ueManEp, rsmEp, A1MediatorEp, routeTable)
 
        for _, endPoint := range endPointList {
                xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
index daf84b8..f82276b 100644 (file)
@@ -51,6 +51,8 @@ var (
                "X2Setup":                          "6",
                "Reset":                            "7",
                "E2_TERM_INIT":                     "1100",
+               "E2_TERM_KEEP_ALIVE_REQ":            "1101",
+               "E2_TERM_KEEP_ALIVE_RESP":           "1102",
                "RAN_CONNECTED":                    "1200",
                "RAN_RESTARTED":                    "1210",
                "RAN_RECONFIGURED":                 "1220",
index 5ad23e0..783f49d 100644 (file)
@@ -60,6 +60,7 @@ type RouteTableEntry struct {
        TxList      EndpointList
        RxGroups    []EndpointList
        SubID       int32
+       RouteType   string
 }
 
 type XApp struct {
@@ -85,12 +86,19 @@ type PlatformComponents []struct {
        Port uint16 `json:"port"`
 }
 
+type E2TInstance struct {
+        Name string `json:"name"`
+        Fqdn string `json:"fqdn"`
+        Ranlist []string `json:"ranlist"`
+}
+
 type ConfigRtmgr struct {
        Pcs PlatformComponents `json:"PlatformComponents"`
 }
 
 type RicComponents struct {
        XApps []XApp
+       E2Ts  map [string]E2TInstance
        Pcs   PlatformComponents
 }
 
index ae63034..9d1380e 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"
 )
 
 const DefaultNngPipelineSocketPrefix = "tcp://"
@@ -106,6 +107,7 @@ func (s *Sbi) updateEndpoints(rcs *rtmgr.RicComponents, sbi Engine) {
                }
        }
        s.updatePlatformEndpoints(&((*rcs).Pcs), sbi)
+        s.updateE2TEndpoints(&((*rcs).E2Ts), sbi)
        s.pruneEndpointList(sbi)
 }
 
@@ -137,3 +139,35 @@ func (s *Sbi) updatePlatformEndpoints(pcs *rtmgr.PlatformComponents, sbi Engine)
                }
        }
 }
+
+func (s *Sbi) updateE2TEndpoints(E2Ts *map[string]rtmgr.E2TInstance, sbi Engine) {
+        xapp.Logger.Debug("updateE2TEndpoints invoked. E2T: %v", *E2Ts)
+        for _, e2t := range *E2Ts {
+                uuid := e2t.Fqdn
+                stringSlice := strings.Split(e2t.Fqdn, ":")
+                ipaddress := stringSlice[0]
+                port, _ := strconv.Atoi(stringSlice[1])
+                if _, ok := rtmgr.Eps[uuid]; ok {
+                        rtmgr.Eps[uuid].Keepalive = true
+                } else {
+                        ep := &rtmgr.Endpoint{
+                                Uuid:       uuid,
+                                Name:       e2t.Name,
+                                XAppType:   PlatformType,
+                                Ip:         ipaddress,
+                                Port:       uint16(port),
+                                TxMessages: rtmgr.PLATFORMMESSAGETYPES[e2t.Name]["tx"],
+                                RxMessages: rtmgr.PLATFORMMESSAGETYPES[e2t.Name]["rx"],
+                                Socket:     nil,
+                                IsReady:    false,
+                                Keepalive:  true,
+                        }
+                        xapp.Logger.Debug("ep created: %v", ep)
+                        if err := sbi.AddEndpoint(ep); err != nil {
+                                xapp.Logger.Error("can't create socket for endpoint: " + ep.Name + " due to:" + err.Error())
+                                continue
+                        }
+                        rtmgr.Eps[uuid] = ep
+                }
+        }
+}
index 841e406..b4f1e8e 100644 (file)
@@ -110,3 +110,26 @@ func (f *File) WriteXApps(file string, xApps *[]rtmgr.XApp) error {
        }
        return nil
 }
+
+func (f *File) WriteNewE2TInstance(file string, E2TInst *rtmgr.E2TInstance) error {
+        xapp.Logger.Debug("Invoked sdl.WriteNewE2TInstance")
+        xapp.Logger.Debug("file.WriteNewE2TInstance writes into file: " + file)
+        xapp.Logger.Debug("file.WriteNewE2TInstance 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())
+        }
+        ricData.E2Ts[E2TInst.Fqdn] = *E2TInst
+
+        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 49e3e8b..f94557e 100644 (file)
@@ -44,4 +44,5 @@ type Engine interface {
        ReadAll(string) (*rtmgr.RicComponents, error)
        WriteAll(string, *rtmgr.RicComponents) error
        WriteXApps(string, *[]rtmgr.XApp) error
+       WriteNewE2TInstance(string, *rtmgr.E2TInstance) error
 }