Skip to content
Snippets Groups Projects
Commit f3cc21ea authored by Ikram Haq's avatar Ikram Haq
Browse files

Refactor appRegistrationPOST and appRegistrationPUT for improved readability,...

Refactor appRegistrationPOST and appRegistrationPUT for improved readability, consistency, and error handling.
parent cce416a9
No related branches found
No related tags found
1 merge request!1Merge CAPIF into MEC Federation branch for ETSI SNS4SNS demo
......@@ -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)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment