2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
23 "e2mgr/providers/httpmsghandlerprovider"
30 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
31 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
32 "github.com/go-ozzo/ozzo-validation"
33 "github.com/go-ozzo/ozzo-validation/is"
34 "github.com/golang/protobuf/jsonpb"
35 "github.com/gorilla/mux"
44 parseErrorCode int = 401
45 validationErrorCode int = 402
46 notFoundErrorCode int = 404
47 internalErrorCode int = 501
48 requiredInputErrorMessage = "Mandatory fields are missing"
49 validationFailedMessage = "Validation failed"
50 parseErrorMessage = "Parse failure"
51 notFoundErrorMessage = "Resource not found"
52 internalErrorMessage = "Internal Server Error. Please try again later"
53 sendMessageErrorMessage = "Failed to send message. For more information please check logs"
56 var E2Sessions = make(sessions.E2Sessions)
58 var messageChannel chan *models.E2RequestMessage
59 var errorChannel chan error
61 type INodebController interface {
62 HandleRequest(writer http.ResponseWriter, request *http.Request)
63 GetNodebIdList (writer http.ResponseWriter, request *http.Request)
64 GetNodeb(writer http.ResponseWriter, request *http.Request)
65 HandleHealthCheckRequest(writer http.ResponseWriter, request *http.Request)
68 type NodebController struct {
69 rmrService *services.RmrService
71 rnibReaderProvider func() reader.RNibReader
72 rnibWriterProvider func() rNibWriter.RNibWriter
75 func NewNodebController(logger *logger.Logger, rmrService *services.RmrService, rnibReaderProvider func() reader.RNibReader,
76 rnibWriterProvider func() rNibWriter.RNibWriter) *NodebController {
77 messageChannel = make(chan *models.E2RequestMessage)
78 errorChannel = make(chan error)
79 return &NodebController{
80 rmrService: rmrService,
82 rnibReaderProvider: rnibReaderProvider,
83 rnibWriterProvider: rnibWriterProvider,
87 func prettifyRequest(request *http.Request) string {
88 dump, _ := httputil.DumpRequest(request, true)
89 requestPrettyPrint := strings.Replace(string(dump), "\r\n", " ", -1)
90 return strings.Replace(requestPrettyPrint, "\n", "", -1)
93 func (rc NodebController) HandleRequest(writer http.ResponseWriter, request *http.Request) {
94 startTime := time.Now()
95 rc.Logger.Infof("[Client -> E2 Manager] #nodeb_controller.HandleRequest - request: %v", prettifyRequest(request))
97 vars := mux.Vars(request)
98 messageTypeParam := vars["messageType"]
99 requestHandlerProvider := httpmsghandlerprovider.NewRequestHandlerProvider(rc.rnibWriterProvider)
100 handler, err := requestHandlerProvider.GetHandler(rc.Logger, messageTypeParam)
103 handleErrorResponse(rc.Logger, http.StatusNotFound, notFoundErrorCode, notFoundErrorMessage, writer, startTime)
107 requestDetails, err := parseJson(rc.Logger, request)
110 handleErrorResponse(rc.Logger, http.StatusBadRequest, parseErrorCode, parseErrorMessage, writer, startTime)
114 rc.Logger.Infof("#nodeb_controller.HandleRequest - request: %+v", requestDetails)
116 if err := validateRequestDetails(rc.Logger, requestDetails); err != nil {
117 handleErrorResponse(rc.Logger, http.StatusBadRequest, validationErrorCode, requiredInputErrorMessage, writer, startTime)
121 err = handler.PreHandle(rc.Logger, &requestDetails)
124 handleErrorResponse(rc.Logger, http.StatusInternalServerError, internalErrorCode, err.Error(), writer, startTime)
128 rc.Logger.Infof("[E2 Manager -> Client] #nodeb_controller.HandleRequest - http status: 200")
129 writer.WriteHeader(http.StatusOK)
131 var wg sync.WaitGroup
133 go handler.CreateMessage(rc.Logger, &requestDetails, messageChannel, E2Sessions, startTime, wg)
135 go rc.rmrService.SendMessage(handler.GetMessageType(), messageChannel, errorChannel, wg)
142 handleErrorResponse(rc.Logger, http.StatusInternalServerError, internalErrorCode, sendMessageErrorMessage, writer, startTime)
146 printHandlingRequestElapsedTimeInMs(rc.Logger, startTime)
149 func (rc NodebController) GetNodebIdList (writer http.ResponseWriter, request *http.Request) {
150 startTime := time.Now()
151 rnibReaderService := services.NewRnibReaderService(rc.rnibReaderProvider)
152 nodebIdList, rnibError := rnibReaderService.GetNodebIdList()
154 if rnibError != nil {
155 rc.Logger.Errorf("%v", rnibError);
156 httpStatusCode, errorCode, errorMessage := rnibErrorToHttpError(rnibError)
157 handleErrorResponse(rc.Logger, httpStatusCode, errorCode, errorMessage, writer, startTime)
161 pmList := utils.ConvertNodebIdListToProtoMessageList(nodebIdList)
162 result, err := utils.MarshalProtoMessageListToJsonArray(pmList)
165 rc.Logger.Errorf("%v", err);
166 handleErrorResponse(rc.Logger, http.StatusInternalServerError, internalErrorCode, internalErrorMessage, writer, startTime)
170 writer.Header().Set("Content-Type", "application/json")
171 rc.Logger.Infof("[E2 Manager -> Client] #nodeb_controller.GetNodebIdList - response: %s", result)
172 writer.Write([]byte(result))
175 func (rc NodebController) GetNodeb(writer http.ResponseWriter, request *http.Request) {
176 startTime := time.Now()
177 vars := mux.Vars(request)
178 ranName := vars["ranName"]
179 // WAS: respondingNode, rnibError := reader.GetRNibReader().GetNodeb(ranName)
180 rnibReaderService := services.NewRnibReaderService(rc.rnibReaderProvider);
181 respondingNode, rnibError := rnibReaderService.GetNodeb(ranName)
182 if rnibError != nil {
183 rc.Logger.Errorf("%v", rnibError)
184 httpStatusCode, errorCode, errorMessage := rnibErrorToHttpError(rnibError)
185 handleErrorResponse(rc.Logger, httpStatusCode, errorCode, errorMessage, writer, startTime)
189 m := jsonpb.Marshaler{}
190 result, err := m.MarshalToString(respondingNode)
193 rc.Logger.Errorf("%v", err)
194 handleErrorResponse(rc.Logger, http.StatusInternalServerError, internalErrorCode, internalErrorMessage, writer, startTime)
198 writer.Header().Set("Content-Type", "application/json")
199 rc.Logger.Infof("[E2 Manager -> Client] #nodeb_controller.GetNodeb - response: %s", result)
200 writer.Write([]byte(result))
203 func (rc NodebController) HandleHealthCheckRequest(writer http.ResponseWriter, request *http.Request) {
204 //fmt.Println("[X-APP -> Client] #HandleHealthCheckRequest - http status: 200")
205 writer.WriteHeader(http.StatusOK)
208 func parseJson(logger *logger.Logger, request *http.Request) (models.RequestDetails, error) {
209 var requestDetails models.RequestDetails
210 if err := json.NewDecoder(request.Body).Decode(&requestDetails); err != nil {
211 logger.Errorf("#nodeb_controller.parseJson - cannot deserialize incoming request. request: %v, error: %v", request, err)
212 return requestDetails, err
214 return requestDetails, nil
217 func validateRequestDetails(logger *logger.Logger, requestDetails models.RequestDetails) error {
219 if requestDetails.RanPort == 0 {
220 logger.Errorf("#nodeb_controller.validateRequestDetails - validation failure: port cannot be zero")
221 return errors.New("port: cannot be blank")
223 err := validation.ValidateStruct(&requestDetails,
224 validation.Field(&requestDetails.RanIp, validation.Required, is.IP),
225 validation.Field(&requestDetails.RanName, validation.Required),
228 logger.Errorf("#nodeb_controller.validateRequestDetails - validation failure, error: %v", err)
234 func handleErrorResponse(logger *logger.Logger, httpStatus int, errorCode int, errorMessage string, writer http.ResponseWriter, startTime time.Time) {
235 errorResponseDetails := models.ErrorResponse{errorCode, errorMessage}
236 errorResponse, _ := json.Marshal(errorResponseDetails)
237 printHandlingRequestElapsedTimeInMs(logger, startTime)
238 logger.Infof("[E2 Manager -> Client] #nodeb_controller.handleErrorResponse - http status: %d, error response: %+v", httpStatus, errorResponseDetails)
239 writer.Header().Set("Content-Type", "application/json")
240 writer.WriteHeader(httpStatus)
241 _, err := writer.Write(errorResponse)
244 logger.Errorf("#nodeb_controller.handleErrorResponse - Cannot send response. writer:%v", writer)
248 func printHandlingRequestElapsedTimeInMs(logger *logger.Logger, startTime time.Time) {
249 logger.Infof("Summary: #nodeb_controller.printElapsedTimeInMs - Elapsed time for handling request from client to E2 termination: %f ms",
250 float64(time.Since(startTime))/float64(time.Millisecond))
253 func rnibErrorToHttpError(rnibError common.IRNibError) (int, int, string) {
254 switch rnibError.GetCode() {
255 case common.RESOURCE_NOT_FOUND:
256 return http.StatusNotFound, notFoundErrorCode, notFoundErrorMessage
257 case common.INTERNAL_ERROR:
258 return http.StatusInternalServerError, internalErrorCode, internalErrorMessage
259 case common.VALIDATION_ERROR:
260 return http.StatusBadRequest, validationErrorCode, validationFailedMessage
262 return http.StatusInternalServerError, internalErrorCode, internalErrorMessage