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.
21 "e2mgr/e2managererrors"
24 "e2mgr/providers/httpmsghandlerprovider"
26 "github.com/gorilla/mux"
35 ParamRanName = "ranName"
39 type INodebController interface {
40 Shutdown(writer http.ResponseWriter, r *http.Request)
41 X2Reset(writer http.ResponseWriter, r *http.Request)
42 X2Setup(writer http.ResponseWriter, r *http.Request)
43 EndcSetup(writer http.ResponseWriter, r *http.Request)
44 GetNodeb(writer http.ResponseWriter, r *http.Request)
45 GetNodebIdList(writer http.ResponseWriter, r *http.Request)
48 type NodebController struct {
50 handlerProvider *httpmsghandlerprovider.IncomingRequestHandlerProvider
53 func NewNodebController(logger *logger.Logger, handlerProvider *httpmsghandlerprovider.IncomingRequestHandlerProvider) *NodebController {
54 return &NodebController{
56 handlerProvider: handlerProvider,
60 func (c *NodebController) GetNodebIdList(writer http.ResponseWriter, r *http.Request) {
61 c.logger.Infof("[Client -> E2 Manager] #NodebController.GetNodebIdList - request: %v", c.prettifyRequest(r))
63 c.handleRequest(writer, &r.Header, httpmsghandlerprovider.GetNodebIdListRequest, nil, false)
66 func (c *NodebController) GetNodeb(writer http.ResponseWriter, r *http.Request) {
67 c.logger.Infof("[Client -> E2 Manager] #NodebController.GetNodeb - request: %v", c.prettifyRequest(r))
69 ranName := vars["ranName"]
70 request := models.GetNodebRequest{RanName: ranName}
71 c.handleRequest(writer, &r.Header, httpmsghandlerprovider.GetNodebRequest, request, false)
74 func (c *NodebController) Shutdown(writer http.ResponseWriter, r *http.Request) {
75 c.logger.Infof("[Client -> E2 Manager] #NodebController.Shutdown - request: %v", c.prettifyRequest(r))
76 c.handleRequest(writer, &r.Header, httpmsghandlerprovider.ShutdownRequest, nil, false)
79 func (c *NodebController) X2Reset(writer http.ResponseWriter, r *http.Request) {
80 c.logger.Infof("[Client -> E2 Manager] #NodebController.X2Reset - request: %v", c.prettifyRequest(r))
81 request := models.ResetRequest{}
83 ranName := vars[ParamRanName]
85 if r.ContentLength > 0 && !c.extractJsonBody(r, &request, writer) {
88 request.RanName = ranName
89 c.handleRequest(writer, &r.Header, httpmsghandlerprovider.ResetRequest, request, false)
92 func (c *NodebController) X2Setup(writer http.ResponseWriter, r *http.Request) {
93 c.logger.Infof("[Client -> E2 Manager] #NodebController.X2Setup - request: %v", c.prettifyRequest(r))
95 request := models.SetupRequest{}
97 if !c.extractJsonBody(r, &request, writer) {
101 c.handleRequest(writer, &r.Header, httpmsghandlerprovider.X2SetupRequest, request, true)
104 func (c *NodebController) EndcSetup(writer http.ResponseWriter, r *http.Request) {
105 c.logger.Infof("[Client -> E2 Manager] #NodebController.EndcSetup - request: %v", c.prettifyRequest(r))
107 request := models.SetupRequest{}
109 if !c.extractJsonBody(r, &request, writer) {
113 c.handleRequest(writer, &r.Header, httpmsghandlerprovider.EndcSetupRequest, request, true)
116 func (c *NodebController) extractJsonBody(r *http.Request, request models.Request, writer http.ResponseWriter) bool {
118 body, err := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
121 c.logger.Errorf("[Client -> E2 Manager] #NodebController.extractJsonBody - unable to extract json body - error: %s", err)
122 c.handleErrorResponse(e2managererrors.NewInvalidJsonError(), writer)
126 err = json.Unmarshal(body, &request)
128 c.logger.Errorf("[Client -> E2 Manager] #NodebController.extractJsonBody - unable to extract json body - error: %s", err)
129 c.handleErrorResponse(e2managererrors.NewInvalidJsonError(), writer)
136 func (c *NodebController) handleRequest(writer http.ResponseWriter, header *http.Header, requestName httpmsghandlerprovider.IncomingRequest, request models.Request, validateHeader bool) {
140 err := c.validateRequestHeader(header)
142 c.handleErrorResponse(err, writer)
147 handler, err := c.handlerProvider.GetHandler(requestName)
150 c.handleErrorResponse(err, writer)
154 response, err := handler.Handle(request)
157 c.handleErrorResponse(err, writer)
162 writer.WriteHeader(http.StatusNoContent)
163 c.logger.Infof("[E2 Manager -> Client] #NodebController.handleRequest - status response: %v", http.StatusNoContent)
167 result, err := response.Marshal()
170 c.handleErrorResponse(err, writer)
174 c.logger.Infof("[E2 Manager -> Client] #NodebController.handleRequest - response: %s", result)
175 writer.Header().Set("Content-Type", "application/json")
176 writer.Write([]byte(result))
179 func (c *NodebController) validateRequestHeader(header *http.Header) error {
181 if header.Get("Content-Type") != "application/json" {
182 c.logger.Errorf("#NodebController.validateRequestHeader - validation failure, incorrect content type")
184 return e2managererrors.NewHeaderValidationError()
189 func (c *NodebController) handleErrorResponse(err error, writer http.ResponseWriter) {
191 var errorResponseDetails models.ErrorResponse
196 case *e2managererrors.RnibDbError:
197 e2Error, _ := err.(*e2managererrors.RnibDbError)
198 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
199 httpError = http.StatusInternalServerError
200 case *e2managererrors.CommandAlreadyInProgressError:
201 e2Error, _ := err.(*e2managererrors.CommandAlreadyInProgressError)
202 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
203 httpError = http.StatusMethodNotAllowed
204 case *e2managererrors.HeaderValidationError:
205 e2Error, _ := err.(*e2managererrors.HeaderValidationError)
206 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
207 httpError = http.StatusUnsupportedMediaType
208 case *e2managererrors.WrongStateError:
209 e2Error, _ := err.(*e2managererrors.WrongStateError)
210 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
211 httpError = http.StatusBadRequest
212 case *e2managererrors.RequestValidationError:
213 e2Error, _ := err.(*e2managererrors.RequestValidationError)
214 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
215 httpError = http.StatusBadRequest
216 case *e2managererrors.InvalidJsonError:
217 e2Error, _ := err.(*e2managererrors.InvalidJsonError)
218 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
219 httpError = http.StatusBadRequest
220 case *e2managererrors.RmrError:
221 e2Error, _ := err.(*e2managererrors.RmrError)
222 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
223 httpError = http.StatusInternalServerError
224 case *e2managererrors.ResourceNotFoundError:
225 e2Error, _ := err.(*e2managererrors.ResourceNotFoundError)
226 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
227 httpError = http.StatusNotFound
228 case *e2managererrors.E2TInstanceAbsenceError:
229 e2Error, _ := err.(*e2managererrors.E2TInstanceAbsenceError)
230 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
231 httpError = http.StatusServiceUnavailable
233 e2Error := e2managererrors.NewInternalError()
234 errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
235 httpError = http.StatusInternalServerError
238 errorResponse, _ := json.Marshal(errorResponseDetails)
240 c.logger.Errorf("[E2 Manager -> Client] #NodebController.handleErrorResponse - http status: %d, error response: %+v", httpError, errorResponseDetails)
242 writer.Header().Set("Content-Type", "application/json")
243 writer.WriteHeader(httpError)
244 _, err = writer.Write(errorResponse)
247 c.logger.Errorf("#NodebController.handleErrorResponse - Cannot send response. writer:%v", writer)
251 func (c *NodebController) prettifyRequest(request *http.Request) string {
252 dump, _ := httputil.DumpRequest(request, true)
253 requestPrettyPrint := strings.Replace(string(dump), "\r\n", " ", -1)
254 return strings.Replace(requestPrettyPrint, "\n", "", -1)