X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=E2Manager%2Fhandlers%2Fhttpmsghandlers%2Fsetup_request_handler.go;h=51e579b173273dab82bb55a14bc696237bb27b5b;hb=7219930da2168712ef420676ebc6aa3f1490ef53;hp=f3cf7b6ee89ce047f75c04ea80899c1627b4f624;hpb=1ec13d4076e7c7abefac6176462c1fee31229213;p=ric-plt%2Fe2mgr.git diff --git a/E2Manager/handlers/httpmsghandlers/setup_request_handler.go b/E2Manager/handlers/httpmsghandlers/setup_request_handler.go index f3cf7b6..51e579b 100644 --- a/E2Manager/handlers/httpmsghandlers/setup_request_handler.go +++ b/E2Manager/handlers/httpmsghandlers/setup_request_handler.go @@ -13,122 +13,212 @@ // 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). package httpmsghandlers import ( - "e2mgr/e2pdus" + "e2mgr/e2managererrors" "e2mgr/logger" - "e2mgr/rNibWriter" - "e2mgr/rnibBuilders" - "fmt" - "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" - "os" - "sync" - "time" - + "e2mgr/managers" "e2mgr/models" - "e2mgr/rmrCgo" - "e2mgr/sessions" + "e2mgr/services" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" + "github.com/go-ozzo/ozzo-validation" + "github.com/go-ozzo/ozzo-validation/is" ) const ( - ENV_RIC_ID = "RIC_ID" - MaxAsn1CodecAllocationBufferSize = 64 * 1024 - MaxAsn1PackedBufferSize = 4096 - MaxAsn1CodecMessageBufferSize = 4096 + X2SetupActivityName = "X2_SETUP" + EndcSetupActivityName = "ENDC_SETUP" ) - -/*The Ric Id is the combination of pLMNId and ENBId*/ -var pLMNId []byte -var eNBId []byte -var eNBIdBitqty uint -var ricFlag = []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ - type SetupRequestHandler struct { - rnibWriterProvider func() rNibWriter.RNibWriter + rNibDataService services.RNibDataService + logger *logger.Logger + ranSetupManager managers.IRanSetupManager + protocol entities.E2ApplicationProtocol + e2tAssociationManager *managers.E2TAssociationManager + e2tInstancesManager managers.IE2TInstancesManager } -func NewSetupRequestHandler(rnibWriterProvider func() rNibWriter.RNibWriter) *SetupRequestHandler { +func NewSetupRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService, + ranSetupManager managers.IRanSetupManager, protocol entities.E2ApplicationProtocol, e2tInstancesManager managers.IE2TInstancesManager, e2tAssociationManager *managers.E2TAssociationManager) *SetupRequestHandler { return &SetupRequestHandler{ - rnibWriterProvider: rnibWriterProvider, + logger: logger, + rNibDataService: rNibDataService, + ranSetupManager: ranSetupManager, + protocol: protocol, + e2tAssociationManager: e2tAssociationManager, + e2tInstancesManager: e2tInstancesManager, } } -func (handler SetupRequestHandler) PreHandle(logger *logger.Logger, details *models.RequestDetails) error { - nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details, entities.E2ApplicationProtocol_X2_SETUP_REQUEST) +func (h *SetupRequestHandler) Handle(request models.Request) (models.IResponse, error) { + + setupRequest := request.(models.SetupRequest) - rNibErr := handler.rnibWriterProvider().SaveNodeb(nodebIdentity, nodebInfo) - if rNibErr != nil { - logger.Errorf("#setup_request_handler.PreHandle - failed to save initial nodeb entity for ran name: %v in RNIB. Error: %s", details.RanName, rNibErr.Error()) - } else { - logger.Infof("#setup_request_handler.PreHandle - initial nodeb entity for ran name: %v was saved to RNIB ", details.RanName) + err := h.validateRequestDetails(setupRequest) + if err != nil { + return nil, err } - return rNibErr -} + nodebInfo, err := h.rNibDataService.GetNodeb(setupRequest.RanName) -func (SetupRequestHandler) CreateMessage(logger *logger.Logger, requestDetails *models.RequestDetails, messageChannel chan *models.E2RequestMessage, e2sessions sessions.E2Sessions, startTime time.Time, wg sync.WaitGroup) { + if err != nil { + _, ok := err.(*common.ResourceNotFoundError) + if !ok { + h.logger.Errorf("#SetupRequestHandler.Handle - failed to get nodeB entity for ran name: %v from RNIB. Error: %s", setupRequest.RanName, err) + return nil, e2managererrors.NewRnibDbError() + } - wg.Add(1) + result := h.connectNewRan(&setupRequest, h.protocol) + return nil, result + } - transactionId := requestDetails.RanName - e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails} - setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, e2pdus.PackedX2setupRequest) + if nodebInfo.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN { + h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN: %s in wrong state (%s)", nodebInfo.RanName, entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)]) + result := e2managererrors.NewWrongStateError(h.getActivityName(h.protocol), entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)]) + return nil, result + } - logger.Debugf("#setup_request_handler.CreateMessage - PDU: %s", e2pdus.PackedX2setupRequestAsString) - logger.Debugf("#setup_request_handler.CreateMessage - setupRequestMessage was created successfully. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage) - messageChannel <- setupRequestMessage + if len(nodebInfo.AssociatedE2TInstanceAddress) != 0 { + result := h.connectExistingRanWithAssociatedE2TAddress(nodebInfo) + return nil, result + } - wg.Done() + result := h.connectExistingRanWithoutAssociatedE2TAddress(nodebInfo) + return nil, result } -//Expected value in RIC_ID = pLMN_Identity-eNB_ID/ -//<6 hex digits>-<6 or 8 hex digits>/<18|20|21|28> -//Each byte is represented by two hex digits, the value in the lowest byte of the eNB_ID must be assigned to the lowest bits -//For example, to get the value of ffffeab/28 the last byte must be 0x0b, not 0xb0 (-ffffea0b/28). -func parseRicID(ricId string) error { - if _, err := fmt.Sscanf(ricId, "%6x-%8x/%2d", &pLMNId, &eNBId, &eNBIdBitqty); err != nil { - return fmt.Errorf("unable to extract the value of %s: %s", ENV_RIC_ID, err) +func createInitialNodeInfo(requestDetails *models.SetupRequest, protocol entities.E2ApplicationProtocol) (*entities.NodebInfo, *entities.NbIdentity) { + + nodebInfo := &entities.NodebInfo{ + Ip: requestDetails.RanIp, + Port: uint32(requestDetails.RanPort), + ConnectionStatus: entities.ConnectionStatus_CONNECTING, + E2ApplicationProtocol: protocol, + RanName: requestDetails.RanName, + ConnectionAttempts: 0, } - if len(pLMNId) < 3 { - return fmt.Errorf("invalid value for %s, len(pLMNId:%v) != 3", ENV_RIC_ID, pLMNId) + nbIdentity := &entities.NbIdentity{ + InventoryName: requestDetails.RanName, } - if len(eNBId) < 3 { - return fmt.Errorf("invalid value for %s, len(eNBId:%v) != 3 or 4", ENV_RIC_ID, eNBId) + return nodebInfo, nbIdentity +} + +func (h *SetupRequestHandler) connectExistingRanWithoutAssociatedE2TAddress(nodebInfo *entities.NodebInfo) error { + e2tAddress, err := h.e2tInstancesManager.SelectE2TInstance() + + if err != nil { + h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed selecting E2T instance", nodebInfo.RanName) + + if nodebInfo.ConnectionStatus == entities.ConnectionStatus_DISCONNECTED && nodebInfo.ConnectionAttempts == 0 { + return err + } + + nodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED + nodebInfo.ConnectionAttempts = 0 + updateError := h.rNibDataService.UpdateNodebInfo(nodebInfo) + + if updateError != nil { + h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed updating nodeb. error: %s", nodebInfo.RanName, updateError) + } + + return err } - if eNBIdBitqty != e2pdus.ShortMacro_eNB_ID && eNBIdBitqty != e2pdus.Macro_eNB_ID && eNBIdBitqty != e2pdus.LongMacro_eNB_ID && eNBIdBitqty != e2pdus.Home_eNB_ID { - return fmt.Errorf("invalid value for %s, eNBIdBitqty: %d", ENV_RIC_ID, eNBIdBitqty) + err = h.e2tAssociationManager.AssociateRan(e2tAddress, nodebInfo) + + if err != nil { + h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed associating ran to e2t address %s. error: %s", nodebInfo.RanName, e2tAddress, err) + return err } - return nil + h.logger.Infof("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - successfully updated nodeb in rNib", nodebInfo.RanName) + + result := h.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING) + return result } -//TODO: remove Get -func (SetupRequestHandler) GetMessageType() int { - return rmrCgo.RIC_X2_SETUP_REQ +func (h *SetupRequestHandler) connectExistingRanWithAssociatedE2TAddress(nodebInfo *entities.NodebInfo) error { + status := entities.ConnectionStatus_CONNECTING + if nodebInfo.ConnectionStatus == entities.ConnectionStatus_CONNECTED { + status = nodebInfo.ConnectionStatus + } + nodebInfo.ConnectionAttempts = 0 + err := h.rNibDataService.UpdateNodebInfo(nodebInfo) + + if err != nil { + h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN name: %s - failed resetting connection attempts of RAN. error: %s", nodebInfo.RanName, err) + return e2managererrors.NewRnibDbError() + } + + h.logger.Infof("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN name: %s - successfully reset connection attempts of RAN", nodebInfo.RanName) + + result := h.ranSetupManager.ExecuteSetup(nodebInfo, status) + return result } -func init() { - var err error - ricId := os.Getenv(ENV_RIC_ID) - //ricId="bbbccc-ffff0e/20" - //ricId="bbbccc-abcd0e/20" - if err = parseRicID(ricId); err != nil { - panic(err) +func (h *SetupRequestHandler) connectNewRan(request *models.SetupRequest, protocol entities.E2ApplicationProtocol) error { + + e2tAddress, err := h.e2tInstancesManager.SelectE2TInstance() + + if err != nil { + h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed selecting E2T instance", request.RanName) + return err } - e2pdus.PackedEndcX2setupRequest,e2pdus.PackedEndcX2setupRequestAsString, err = e2pdus.PreparePackedEndcX2SetupRequest(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize,pLMNId, eNBId, eNBIdBitqty, ricFlag ) - if err != nil{ - panic(err) + nodebInfo, nodebIdentity := createInitialNodeInfo(request, protocol) + + err = h.rNibDataService.SaveNodeb(nodebIdentity, nodebInfo) + + if err != nil { + h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed to save initial nodeb entity in RNIB. error: %s", request.RanName, err) + return e2managererrors.NewRnibDbError() + } + + h.logger.Infof("#SetupRequestHandler.connectNewRan - RAN name: %s - initial nodeb entity was saved to rNib", request.RanName) + + err = h.e2tAssociationManager.AssociateRan(e2tAddress, nodebInfo) + + if err != nil { + h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed associating ran to e2t address %s. error: %s", request.RanName, e2tAddress, err) + return err } - e2pdus.PackedX2setupRequest,e2pdus.PackedX2setupRequestAsString, err = e2pdus.PreparePackedX2SetupRequest(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize,pLMNId, eNBId, eNBIdBitqty, ricFlag ) - if err != nil{ - panic(err) + + result := h.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING) + + return result +} + +func (handler *SetupRequestHandler) validateRequestDetails(request models.SetupRequest) error { + + if request.RanPort == 0 { + handler.logger.Errorf("#SetupRequestHandler.validateRequestDetails - validation failure: port cannot be zero") + return e2managererrors.NewRequestValidationError() + } + err := validation.ValidateStruct(&request, + validation.Field(&request.RanIp, validation.Required, is.IP), + validation.Field(&request.RanName, validation.Required), + ) + + if err != nil { + handler.logger.Errorf("#SetupRequestHandler.validateRequestDetails - validation failure, error: %v", err) + return e2managererrors.NewRequestValidationError() + } + + return nil +} + +func (handler *SetupRequestHandler) getActivityName(protocol entities.E2ApplicationProtocol) string { + if protocol == entities.E2ApplicationProtocol_X2_SETUP_REQUEST { + return X2SetupActivityName } + return EndcSetupActivityName }