diff --git a/go-apps/meep-app-enablement/server/app-support/app-support.go b/go-apps/meep-app-enablement/server/app-support/app-support.go index 1e1e897df2d3fcdb59f93a3115224f03af26bf75..e4f2ca46dab4a6b022b2e830efc536c35ee433de 100644 --- a/go-apps/meep-app-enablement/server/app-support/app-support.go +++ b/go-apps/meep-app-enablement/server/app-support/app-support.go @@ -655,109 +655,106 @@ func timingCurrentTimeGET(w http.ResponseWriter, r *http.Request) { * @return {error} error An error will return if occurs */ func appRegistrationPOST(w http.ResponseWriter, r *http.Request) { - log.Debug(">>> appRegistrationPOST: ", r) + log.Debug(">>> appRegistrationPOST:", r) w.Header().Set("Content-Type", "application/json; charset=UTF-8") - // Decode the request body into AppInfo struct + // Parse request body into AppInfo struct var appInfo AppInfo - err := json.NewDecoder(r.Body).Decode(&appInfo) - if err != nil { - log.Error(err.Error()) - errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) + if err := json.NewDecoder(r.Body).Decode(&appInfo); err != nil { + log.Error("Error decoding request body:", err) + errHandlerProblemDetails(w, "Invalid request body.", http.StatusBadRequest) return } - log.Info("appRegistrationPOST: appInfo: ", appInfo) + log.Info("appRegistrationPOST: Received appInfo:", appInfo) - // Validation of mandatory parameters + // Validate required fields if appInfo.AppName == "" { - log.Error("Mandatory AppName parameter not present") - errHandlerProblemDetails(w, "Mandatory AppName parameter not present", http.StatusBadRequest) + log.Error("Missing mandatory parameter: AppName") + errHandlerProblemDetails(w, "Mandatory attribute AppName is missing.", http.StatusBadRequest) return } if appInfo.AppInstanceId == "" { - log.Error("Mandatory appInstanceId parameter should be present") - errHandlerProblemDetails(w, "Mandatory attribute appInstanceId is missing in the request body.", http.StatusBadRequest) + log.Error("Missing mandatory parameter: AppInstanceId") + errHandlerProblemDetails(w, "Mandatory attribute AppInstanceId is missing.", http.StatusBadRequest) return } if !appInfo.IsInsByMec && appInfo.Endpoint == nil { - log.Error("Shall be present when IsInsByMec is FALSE") - errHandlerProblemDetails(w, "Endpoint shall be present when IsInsByMec is FALSE.", http.StatusBadRequest) + log.Error("Endpoint is required when IsInsByMec is FALSE") + errHandlerProblemDetails(w, "Endpoint is required when IsInsByMec is FALSE.", http.StatusBadRequest) return } - // Process appProfile if present + + // Process appProfile if provided if appInfo.AppProfile != nil { - // Validate appProvider, endpoint, and other fields as per mapping to EASProfile + // Validate appProvider and other fields mapped to EASProfile if appInfo.AppProvider != appInfo.AppProfile.ProvId { - log.Error("appProvider in AppInfo does not match provId in appProfile") - errHandlerProblemDetails(w, "appProvider and provId must be consistent", http.StatusBadRequest) + log.Error("Mismatch between appProvider in AppInfo and provId in appProfile") + errHandlerProblemDetails(w, "appProvider and provId must match.", http.StatusBadRequest) return } - if appInfo.AppProfile != nil { - if !reflect.DeepEqual(getEndpointUris(appInfo.Endpoint), getProfileEndpointUris(appInfo.AppProfile.EndPt)) { - log.Error("endpoint in AppInfo does not match endPt in appProfile") - errHandlerProblemDetails(w, "Endpoint and endPt must be consistent", http.StatusBadRequest) - return - } + if !reflect.DeepEqual(getEndpointUris(appInfo.Endpoint), getProfileEndpointUris(appInfo.AppProfile.EndPt)) { + log.Error("Mismatch between endpoint in AppInfo and endPt in appProfile") + errHandlerProblemDetails(w, "Endpoint and endPt must match.", http.StatusBadRequest) + return } if appInfo.AppProfile.EasId == "" { - log.Error("Mandatory easId parameter should be present") - errHandlerProblemDetails(w, "Mandatory attribute easId is missing in the request body.", http.StatusBadRequest) + log.Error("Missing mandatory parameter: easId") + errHandlerProblemDetails(w, "Mandatory attribute easId is missing.", http.StatusBadRequest) return } if appInfo.AppName != appInfo.AppProfile.EasId { - log.Error("AppName in AppInfo does not match EasId in appProfile") - errHandlerProblemDetails(w, "AppName and EasId must be consistent", http.StatusBadRequest) + log.Error("Mismatch between AppName in AppInfo and EasId in appProfile") + errHandlerProblemDetails(w, "AppName and EasId must match.", http.StatusBadRequest) return } - // Additional consistency checks for fields like scheds, svcArea, etc., based on appProfile attributes + // Additional checks for attributes such as scheds, svcArea, etc., as required. } - // Get App instance - log.Info("appRegistrationPOST: appInfo.AppInstanceId: ", appInfo.AppInstanceId) + // Retrieve App instance information + log.Info("appRegistrationPOST: Processing AppInstanceId:", appInfo.AppInstanceId) appId, err := getAppInfo(appInfo.AppInstanceId) if err != nil { - log.Error(err.Error()) - errHandlerProblemDetails(w, err.Error(), http.StatusNotFound) + log.Error("Error retrieving app instance:", err) + errHandlerProblemDetails(w, "App instance not found.", http.StatusNotFound) return } - log.Info("appRegistrationPOST: appId: ", appId) + log.Info("appRegistrationPOST: Retrieved appId:", appId) - // Validate App info + // Validate the retrieved AppInfo code, problemDetails, err := validateAppInfo(appId) if err != nil { - log.Error(err.Error()) + log.Error("Error validating app info:", err) if problemDetails != "" { w.WriteHeader(code) fmt.Fprint(w, problemDetails) } else { - errHandlerProblemDetails(w, err.Error(), code) + errHandlerProblemDetails(w, "Validation error.", code) } return } - // Set the application info in Redis + // Store AppInfo in Redis keyName := baseKey + "appInfo:" + appInfo.AppInstanceId - log.Info("appRegistrationPOST: keyName: ", keyName) + log.Info("appRegistrationPOST: Storing data with key:", keyName) if err := rc.JSONSetEntry(keyName, ".", convertAppInfoToJson(&appInfo)); err != nil { - log.Error("Unable to store new Registration in redis") - errHandlerProblemDetails(w, "Unable to store new Registration in redis", http.StatusInternalServerError) + log.Error("Failed to store registration in Redis:", err) + errHandlerProblemDetails(w, "Server error. Could not store registration.", http.StatusInternalServerError) return } - // Create a unique link for every subscription and concatenate subscription to it + // Generate resource URI for the created app registration resourceURI := hostUrl.String() + basePath + "registrations/" + appInfo.AppInstanceId - log.Info("appRegistrationPOST: resourceUDI: ", resourceURI) + log.Info("appRegistrationPOST: Generated resource URI:", resourceURI) w.Header().Set("Location", resourceURI) - // Prepare & send response + // Send JSON response with status 201 Created jsonResponse := convertAppInfoToJson(&appInfo) - // On successful registration, return 201 Created with the response body w.WriteHeader(http.StatusCreated) fmt.Fprint(w, jsonResponse) } @@ -834,90 +831,91 @@ func appRegistrationGET(w http.ResponseWriter, r *http.Request) { * @return {error} error An error will return if occurs */ func appRegistrationPUT(w http.ResponseWriter, r *http.Request) { - log.Debug(">>> appRegistrationPUT: ", r) + log.Debug(">>> appRegistrationPUT:", r) w.Header().Set("Content-Type", "application/json; charset=UTF-8") vars := mux.Vars(r) appInstanceId := vars["appInstanceId"] - log.Info("appRegistrationPUT: appInstanceId: ", appInstanceId) + log.Info("appRegistrationPUT: Received appInstanceId:", appInstanceId) - // Read JSON input stream provided in the Request, and stores it in the buffer of a Decoder object - decoder := json.NewDecoder(r.Body) - // Decode function return strings containing the text provided in the request body + // Decode JSON input from request body into AppInfo structure var appInfoPut AppInfo - err := decoder.Decode(&appInfoPut) - if err != nil { - log.Error(err.Error()) - errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) + if err := json.NewDecoder(r.Body).Decode(&appInfoPut); err != nil { + log.Error("Error decoding request body:", err) + errHandlerProblemDetails(w, "Invalid request body.", http.StatusBadRequest) return } - log.Info("appRegistrationPUT: appInfoPut: ", appInfoPut) + log.Info("appRegistrationPUT: Parsed appInfoPut:", appInfoPut) + // Check if the appInfo exists in Redis for the given appInstanceId keyName := baseKey + "appInfo:" + appInstanceId - log.Info("appRegistrationPUT: keyName: ", keyName) + log.Info("appRegistrationPUT: Checking existence of key:", keyName) jsonAppInfo, _ := rc.JSONGetEntry(keyName, ".") if jsonAppInfo == "" { - log.Error("appInfo not found against the provided appInstanceId") - errHandlerProblemDetails(w, "appInfo not found against the provided appInstanceId", http.StatusNotFound) + log.Error("No appInfo found for provided appInstanceId") + errHandlerProblemDetails(w, "appInfo not found for the provided appInstanceId", http.StatusNotFound) return } - if appInfoPut.AppInstanceId != "" { - if appInstanceId != appInfoPut.AppInstanceId { - log.Error("appInstnaceId provided in endpoint and in request body not matching") - errHandlerProblemDetails(w, "appInstanceId provided in endpoint and in request body not matching", http.StatusNotFound) - return - } + // Validate appInstanceId consistency between URL and request body + if appInfoPut.AppInstanceId != "" && appInstanceId != appInfoPut.AppInstanceId { + log.Error("appInstanceId mismatch between endpoint and request body") + errHandlerProblemDetails(w, "appInstanceId in endpoint and request body do not match", http.StatusBadRequest) + return } + // Validate required parameters if appInfoPut.AppName == "" { - log.Error("Mandatory AppName parameter not present") - errHandlerProblemDetails(w, "Mandatory AppName parameter not present", http.StatusBadRequest) + log.Error("Missing mandatory parameter: AppName") + errHandlerProblemDetails(w, "Mandatory attribute AppName is missing.", http.StatusBadRequest) return } if !appInfoPut.IsInsByMec && appInfoPut.Endpoint == nil { - log.Error("Shall be present when IsInsByMec is FALSE") - errHandlerProblemDetails(w, "Shall be present when IsInsByMec is FALSE.", http.StatusBadRequest) + log.Error("Endpoint is required when IsInsByMec is FALSE") + errHandlerProblemDetails(w, "Endpoint is required when IsInsByMec is FALSE.", http.StatusBadRequest) return } - // Process appProfile if present + + // Process appProfile if provided if appInfoPut.AppProfile != nil { - // Validate appProvider, endpoint, and other fields as per mapping to EASProfile + // Validate appProvider and associated fields as per EASProfile mapping if appInfoPut.AppProvider != appInfoPut.AppProfile.ProvId { - log.Error("appProvider in AppInfo does not match provId in appProfile") - errHandlerProblemDetails(w, "appProvider and provId must be consistent", http.StatusBadRequest) + log.Error("Mismatch between appProvider in AppInfo and provId in appProfile") + errHandlerProblemDetails(w, "appProvider and provId must match.", http.StatusBadRequest) return } - if appInfoPut.AppProfile != nil { - if !reflect.DeepEqual(getEndpointUris(appInfoPut.Endpoint), getProfileEndpointUris(appInfoPut.AppProfile.EndPt)) { - log.Error("endpoint in AppInfo does not match endPt in appProfile") - errHandlerProblemDetails(w, "Endpoint and endPt must be consistent", http.StatusBadRequest) - return - } + if !reflect.DeepEqual(getEndpointUris(appInfoPut.Endpoint), getProfileEndpointUris(appInfoPut.AppProfile.EndPt)) { + log.Error("Mismatch between endpoint in AppInfo and endPt in appProfile") + errHandlerProblemDetails(w, "Endpoint and endPt must match.", http.StatusBadRequest) + return } + if appInfoPut.AppProfile.EasId == "" { - log.Error("Mandatory easId parameter should be present") - errHandlerProblemDetails(w, "Mandatory attribute easId is missing in the request body.", http.StatusBadRequest) + log.Error("Missing mandatory parameter: easId") + errHandlerProblemDetails(w, "Mandatory attribute easId is missing.", http.StatusBadRequest) return } + if appInfoPut.AppName != appInfoPut.AppProfile.EasId { - log.Error("AppName in AppInfo does not match EasId in appProfile") - errHandlerProblemDetails(w, "AppName and EasId must be consistent", http.StatusBadRequest) + log.Error("Mismatch between AppName in AppInfo and EasId in appProfile") + errHandlerProblemDetails(w, "AppName and EasId must match.", http.StatusBadRequest) return } - // Additional consistency checks for fields like scheds, svcArea, etc., based on appProfile attributes + // Additional consistency checks for fields such as scheds, svcArea, etc., as required. } + // Set appInstanceId in appInfoPut and store in Redis appInfoPut.AppInstanceId = appInstanceId - - // Store appInfo key in redis - err = rc.JSONSetEntry(baseKey+"appInfo:"+appInstanceId, ".", convertAppInfoToJson(&appInfoPut)) - if err != nil { - log.Error("Failed to store AppInfo in the redis DB: ", err) + log.Info("appRegistrationPUT: Storing updated appInfo for appInstanceId:", appInstanceId) + if err := rc.JSONSetEntry(keyName, ".", convertAppInfoToJson(&appInfoPut)); err != nil { + log.Error("Failed to store updated AppInfo in Redis:", err) + errHandlerProblemDetails(w, "Server error. Could not store updated appInfo.", http.StatusInternalServerError) + return } + // Respond with status 204 No Content to indicate successful update w.WriteHeader(http.StatusNoContent) }