From: rangajal Date: Tue, 10 Dec 2019 09:37:08 +0000 (+0000) Subject: Create E2T API implementation and yaml change for multiple e2t instances handling... X-Git-Tag: 0.4.9~7 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=749099bc00ec6cad5da19846e65bd5b4bd9b8de4;p=ric-plt%2Frtmgr.git Create E2T API implementation and yaml change for multiple e2t instances handling feature Change-Id: I22cbd45c54aa0072159b9c2f041355d5ddc51b69 Signed-off-by: rangajal --- diff --git a/RELNOTES b/RELNOTES index a5fb036..20b981c 100644 --- 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 diff --git a/api/routing_manager.yaml b/api/routing_manager.yaml index f4f852d..c2dacfa 100644 --- a/api/routing_manager.yaml +++ b/api/routing_manager.yaml @@ -14,14 +14,9 @@ # 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" diff --git a/container-tag.yaml b/container-tag.yaml index 2af355a..cfdbfb8 100644 --- a/container-tag.yaml +++ b/container-tag.yaml @@ -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 diff --git a/pkg/nbi/httprestful.go b/pkg/nbi/httprestful.go index db8129e..5e90bfa 100644 --- a/pkg/nbi/httprestful.go +++ b/pkg/nbi/httprestful.go @@ -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 } diff --git a/pkg/nbi/types.go b/pkg/nbi/types.go index dd184d2..78f99a5 100644 --- a/pkg/nbi/types.go +++ b/pkg/nbi/types.go @@ -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 diff --git a/pkg/rpe/rmr.go b/pkg/rpe/rmr.go index 8929c63..6fc8c9f 100644 --- a/pkg/rpe/rmr.go +++ b/pkg/rpe/rmr.go @@ -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 } diff --git a/pkg/rpe/rpe.go b/pkg/rpe/rpe.go index 35006c8..9a963c7 100644 --- a/pkg/rpe/rpe.go +++ b/pkg/rpe/rpe.go @@ -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) diff --git a/pkg/rtmgr/rtmgr.go b/pkg/rtmgr/rtmgr.go index daf84b8..f82276b 100644 --- a/pkg/rtmgr/rtmgr.go +++ b/pkg/rtmgr/rtmgr.go @@ -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", diff --git a/pkg/rtmgr/types.go b/pkg/rtmgr/types.go index 5ad23e0..783f49d 100644 --- a/pkg/rtmgr/types.go +++ b/pkg/rtmgr/types.go @@ -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 } diff --git a/pkg/sbi/sbi.go b/pkg/sbi/sbi.go index ae63034..9d1380e 100644 --- a/pkg/sbi/sbi.go +++ b/pkg/sbi/sbi.go @@ -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 + } + } +} diff --git a/pkg/sdl/file.go b/pkg/sdl/file.go index 841e406..b4f1e8e 100644 --- a/pkg/sdl/file.go +++ b/pkg/sdl/file.go @@ -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 +} diff --git a/pkg/sdl/types.go b/pkg/sdl/types.go index 49e3e8b..f94557e 100644 --- a/pkg/sdl/types.go +++ b/pkg/sdl/types.go @@ -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 }