package nbi import ( "bytes" "fmt" "net/http" "strings" "be.ems/lib/dborm" "github.com/go-resty/resty/v2" "github.com/gorilla/mux" "be.ems/lib/global" "be.ems/lib/log" "be.ems/lib/oauth" "be.ems/lib/services" "be.ems/lib/session" "be.ems/restagent/config" ) type ErrorOAuthResponse struct { Error map[string]interface{} } type FailOAuthResponse struct { Error struct { ErrorCode string ErrorInfo string } } type ApiResponse struct { ResultCode string ResultMessage interface{} } var globalSession = session.NewSessManager("restagent") var ( MAX_RMUID_NUM int MAX_ALARMID_NUM int MAX_PMUID_NUM int MAX_SUBID_NUM int MAX_URI_LEN int RMUID_REGEXP string ) var ( // Northbound interface GetNRMUri = config.DefaultUriPrefix + "/resourceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}" NorthboundGetAlarmUri = config.DefaultUriPrefix + "/faultManagement/{apiVersion}/alarms" // ?alarmIds={alarmIdValues} CustomGetNRMUri = config.UriPrefix + "/resourceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}" ) func CheckParameterName(r *http.Request) []string { var errorParams []string vars := r.URL.Query() for k, v := range vars { log.Debug("vars:", k, v) if k != "rmUIDs" && k != "fields" { errorParams = append(errorParams, k) } } return errorParams } func GetRmUIDArr(r *http.Request) []string { vars := r.URL.Query() rmUIDs, ok := vars["rmUIDs"] if !ok { log.Debug("rmUIDs is not exist") return nil } var rmUIDValues []string for _, r := range rmUIDs { if r != "" { rmUIDValues = global.MergeStringArr(rmUIDValues, strings.Split(r, `,`)) } } return rmUIDValues } func GetAttrNameArr(r *http.Request) []string { vars := r.URL.Query() fields, ok := vars["fields"] if !ok { log.Debug("attributeNames does not exist") return nil } var attrNames []string for _, a := range fields { if a != "" { attrNames = global.MergeStringArr(attrNames, strings.Split(a, `,`)) } } return attrNames } func CheckValidRmUID(rmUIDs []string) []string { log.Debug("CheckValidRmUID processing... ") var invalidRmUIDs []string for _, r := range rmUIDs { if !global.MatchRmUID(RMUID_REGEXP, r) { invalidRmUIDs = append(invalidRmUIDs, r) } } return invalidRmUIDs } func CheckLocalRmUID(rmUIDs []string) string { log.Debug("GetLocalRmUID processing... ") rmUID := config.GetRmUIDFromConfig() for _, r := range rmUIDs { if r == rmUID { return rmUID } } return "" } func NBIGetNRMFromNF(w http.ResponseWriter, r *http.Request) { log.Debug("NBIGetNRMFromNF processing... ") // response 414-4 uri too long ? (optional) // todo ... ? if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() { log.Error("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig()) services.ResponseRequestURITooLong414UriTooLong(w) return } // check media type(content type) only support "application/json" // response 415-1 if !services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) { log.Debug("Invalid Content-Type") services.ResponseUnsupportedMediaType415(w) return } // error processing ... // 401-1 response token, ret := oauth.IsCarriedToken(r) if ret == false { log.Error("AccessToken is not carried") services.ResponseUnauthorized401AccessTokenNotCarried(w) return } // 401-2 response if dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) == false { log.Error("AccessToken fails or does not exist") services.ResponseUnauthorized401AccessTokenNotExist(w) return } _, err := dborm.XormUpdateSessionShakeTime(token) if err != nil { log.Error("Failed to update session table:", err) services.ResponseUnauthorized401AccessTokenNotExist(w) return } /* // response 403 Forbidden, permissions deny // todo... plist := globalSession.GetPermissionFromSession(token) log.Debug("permission list:", plist) if len(plist) == 0 || plist[0] == false { log.Debug("User permission deny") services.ResponseForbidden403NotPermission(w) return } */ vars := mux.Vars(r) neType := vars["elementTypeValue"] apiVer := vars["apiVersion"] if apiVer != "v1" { log.Error("Uri is invalid") services.ResponseNotFound404UriNotExist(w, r) return } // response 406-1 rmUIDValues := GetRmUIDArr(r) if rmUIDValues == nil { log.Error("missing parameter: rmUIDs") services.ResponseNotAcceptable406MissingParam(w) return } // response 406-2 errorParams := CheckParameterName(r) if errorParams != nil { log.Error("parameter name error: ", errorParams) services.ResponseNotAcceptable406ParamError(w, errorParams) return } // response 400-5 if len(rmUIDValues) == 0 { log.Error("rmUIDs is wrong or NULL") services.ResponseBadRequest400WrongParamValue(w) return } // response 414-1 if len(rmUIDValues) > config.GetYamlConfig().Params.RmUIDMaxNum { log.Error("rmUID greater than", config.GetYamlConfig().Params.RmUIDMaxNum) services.ResponseRequestURITooLong414NRMNumExceed(w, config.GetYamlConfig().Params.RmUIDMaxNum) return } var response *resty.Response respMsg := make(map[string]interface{}) for _, rmUID := range rmUIDValues { neInfo, err := dborm.XormGetNeInfoByRmUID(neType, rmUID) if err != nil { log.Error("dborm.XormGetNeInfo is failed:", err) services.ResponseInternalServerError500DatabaseOperationFailed(w) return } requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI) log.Debug("requestURI2NF: GET ", requestURI2NF) client := resty.New() response, err = client.R(). EnableTrace(). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) if err != nil { log.Error("Failed to Get from NF:", err) services.ResponseInternalServerError500NFConnectRefused(w) return } switch response.StatusCode() { case http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusCreated: respMsg["data"] = response default: if response != nil { services.TransportResponse(w, response.StatusCode(), response.Body()) } } } services.TransportResponse(w, response.StatusCode(), response.Body()) }