Loading go-apps/meep-ams/server/ams.go +313 −15 Original line number Diff line number Diff line Loading @@ -148,6 +148,19 @@ func notImplemented(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } type RegisterationInfoList struct { Registrations []RegistrationInfo Filters *FilterParameters } type FilterParameters struct { filter string all_fields string fields string exclude_fields string exclude_default string } // Init - App Mobility Service initialization func Init() (err error) { Loading Loading @@ -1205,8 +1218,10 @@ func subscriptionLinkListSubscriptionsGet(w http.ResponseWriter, r *http.Request u, _ := url.Parse(r.URL.String()) q := u.Query() validQueryParams := []string{"subscriptionType"} if !validateQueryParams(q, validQueryParams) { w.WriteHeader(http.StatusBadRequest) err := validateQueryParams(q, validQueryParams) if err != nil { errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) return } Loading Loading @@ -1475,18 +1490,46 @@ func appMobilityServiceByIdDELETE(w http.ResponseWriter, r *http.Request) { func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") // Validate query parameters u, _ := url.Parse(r.URL.String()) q := u.Query() validParams := []string{"filter", "All_fields", "Fields", "Exclude_fields", "Exclude_default"} err := validateQueryParams(q, validParams) if err != nil { print("Query Parameter error") errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) return } // Parse query parameters filters := q.Get("filter") allFields := q.Get("all_fields") // field := q["fields"] // excludeFields := q["exclude_fields"] // excludeDefault := q.Get("exclude_default") regInfoList := &RegisterationInfoList{ Filters: &FilterParameters{ filter: filters, all_fields: allFields, }, Registrations: make([]RegistrationInfo, 0), } // Get all AMS Registration Info regInfoList := make([]RegistrationInfo, 0) //regInfoList := make([]RegistrationInfo, 0) key := baseKey + "svc:*:info" err := rc.ForEachJSONEntry(key, populateRegInfoList, ®InfoList) err = rc.ForEachJSONEntry(key, populateRegInfoList, regInfoList) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) return } // Send response jsonResponse, err := json.Marshal(regInfoList) // Prepare & send response jsonResponse, err := json.Marshal(regInfoList.Registrations) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) Loading @@ -1498,21 +1541,275 @@ func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) { } func populateRegInfoList(key string, jsonEntry string, response interface{}) error { regInfoList := response.(*[]RegistrationInfo) if regInfoList == nil { return errors.New("Response not defined") data := response.(*RegisterationInfoList) if data == nil { return errors.New("response not defined") } // Retrieve registration info from DB var regInfo RegistrationInfo err := json.Unmarshal([]byte(jsonEntry), ®Info) println("keysss", key) if err != nil { return err } *regInfoList = append(*regInfoList, regInfo) // Filter services if data.Filters != nil { if data.Filters.filter != "" { filterField := data.Filters.filter // Split filterField into operator, attribute, and value filterField = strings.Trim(filterField, "()") filterParts := strings.SplitN(filterField, ",", 3) if len(filterParts) != 3 { return nil } operator := filterParts[0] attribute := filterParts[1] value := filterParts[2] // Apply filters based on attribute switch attribute { case "appMobilityServiceId": if !applyStringFilter(operator, regInfo.AppMobilityServiceId, value) { return nil } case "serviceConsumerId.appInstanceId": if !applyStringFilter(operator, regInfo.ServiceConsumerId.AppInstanceId, value) { return nil } case "serviceConsumerId.mepId": if !applyStringFilter(operator, regInfo.ServiceConsumerId.MepId, value) { return nil } case "deviceInformation.associateId": matched := false for _, deviceInfo := range regInfo.DeviceInformation { if applyStringFilter(operator, deviceInfo.AssociateId.Value, value) { matched = true break } } if !matched { return nil } // case "deviceInformation.contextTransferState": // matched := false // for _, deviceInfo := range regInfo.DeviceInformation { // if applyEnumFilter(operator, string(deviceInfo.ContextTransferState.val), value) { // matched = true // break // } // } // if !matched { // return fmt.Errorf("filter mismatch: deviceInformation.contextTransferState") // } case "expiryTime": expiryTime, err := strconv.ParseUint(value, 10, 32) if err != nil { return nil } if !applyNumericFilter(operator, uint32(regInfo.ExpiryTime), uint32(expiryTime)) { return nil } default: return nil } } } data.Registrations = append(data.Registrations, regInfo) return nil } // Helper functions for applying filters func applyStringFilter(operator, fieldValue, filterValue string) bool { switch operator { case "eq": return fieldValue == filterValue case "neq": return fieldValue != filterValue case "cont": return strings.Contains(fieldValue, filterValue) case "ncont": return !strings.Contains(fieldValue, filterValue) case "in": values := strings.Split(filterValue, ",") for _, v := range values { if fieldValue == v { return true } } return false case "nin": values := strings.Split(filterValue, ",") for _, v := range values { if fieldValue == v { return false } } return true case "gt": return fieldValue > filterValue case "gte": return fieldValue >= filterValue case "lt": return fieldValue < filterValue case "lte": return fieldValue <= filterValue default: return false } } func applyEnumFilter(operator, fieldValue, filterValue string) bool { return applyStringFilter(operator, fieldValue, filterValue) } func applyNumericFilter(operator string, fieldValue, filterValue uint32) bool { switch operator { case "eq": return fieldValue == filterValue case "neq": return fieldValue != filterValue case "gt": return fieldValue > filterValue case "gte": return fieldValue >= filterValue case "lt": return fieldValue < filterValue case "lte": return fieldValue <= filterValue default: return false } } // Original // func populateRegInfoList(key string, jsonEntry string, response interface{}) error { // data := response.(*RegisterationInfoList) // if data == nil { // return errors.New("response not defined") // } // // Retrieve registration info from DB // var regInfo RegistrationInfo // err := json.Unmarshal([]byte(jsonEntry), ®Info) // println("keysss", key) // if err == nil { // return err // } // // Filter services // if data.Filters != nil { // if data.Filters.filter != "" { // filterField := data.Filters.filter // if regInfo.AppMobilityServiceId == "" || (filterField != regInfo.AppMobilityServiceId) { // return nil // } // } // } // data.Registrations = append(data.Registrations, regInfo) // return nil // } // filterRegistrationInfo applies filtering based on the provided filters. // func filterRegistrationInfo(regInfoList []RegistrationInfo, filters []string) []RegistrationInfo { // var filteredList []RegistrationInfo // for _, regInfo := range regInfoList { // match := true // // Iterate over filters to apply them one by one // for _, filter := range filters { // filterParts := strings.Split(filter, ":") // if len(filterParts) != 2 { // // Invalid filter format (e.g., "key:value") // continue // } // key := filterParts[0] // value := filterParts[1] // // Apply filter based on key-value pairs // switch key { // case "appMobilityServiceId": // if regInfo.AppMobilityServiceId != value { // match = false // } // case "appInstanceId": // if regInfo.ServiceConsumerId.AppInstanceId != value { // match = false // } // case "mepId": // if regInfo.ServiceConsumerId.MepId != value { // match = false // } // case "associateId": // // Check if any device has the associateId value // found := false // for _, device := range regInfo.DeviceInformation { // if device.AssociateId == value { // found = true // break // } // } // if !found { // match = false // } // case "expiryTime": // expiryTime, err := strconv.Atoi(value) // if err != nil || regInfo.ExpiryTime != uint32(expiryTime) { // match = false // } // default: // // If filter key is not recognized, skip it // continue // } // // If any filter condition doesn't match, we stop checking further // if !match { // break // } // } // // If all filters matched, add to the result list // if match { // filteredList = append(filteredList, regInfo) // } // } // return filteredList // } // func populateRegInfoList(key string, jsonEntry string, response interface{}) error { // regInfoList := response.(*[]RegistrationInfo) // if regInfoList == nil { // return errors.New("Response not defined") // } // // Retrieve registration info from DB // var regInfo RegistrationInfo // err := json.Unmarshal([]byte(jsonEntry), ®Info) // if err != nil { // return err // } // *regInfoList = append(*regInfoList, regInfo) // return nil // } func cleanUp() { log.Info("Terminate all") Loading Loading @@ -2324,21 +2621,22 @@ func delTrackedDevInfo(svcId string, address string) error { return nil } func validateQueryParams(params url.Values, validParamList []string) bool { func validateQueryParams(params url.Values, validParams []string) error { for param := range params { found := false for _, validParam := range validParamList { for _, validParam := range validParams { if param == validParam { found = true break } } if !found { log.Error("Invalid query param: ", param) return false err := errors.New("Invalid query param: " + param) log.Error(err.Error()) return err } } return true return nil } func validateQueryParamValue(val string, validValues []string) bool { Loading Loading
go-apps/meep-ams/server/ams.go +313 −15 Original line number Diff line number Diff line Loading @@ -148,6 +148,19 @@ func notImplemented(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } type RegisterationInfoList struct { Registrations []RegistrationInfo Filters *FilterParameters } type FilterParameters struct { filter string all_fields string fields string exclude_fields string exclude_default string } // Init - App Mobility Service initialization func Init() (err error) { Loading Loading @@ -1205,8 +1218,10 @@ func subscriptionLinkListSubscriptionsGet(w http.ResponseWriter, r *http.Request u, _ := url.Parse(r.URL.String()) q := u.Query() validQueryParams := []string{"subscriptionType"} if !validateQueryParams(q, validQueryParams) { w.WriteHeader(http.StatusBadRequest) err := validateQueryParams(q, validQueryParams) if err != nil { errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) return } Loading Loading @@ -1475,18 +1490,46 @@ func appMobilityServiceByIdDELETE(w http.ResponseWriter, r *http.Request) { func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") // Validate query parameters u, _ := url.Parse(r.URL.String()) q := u.Query() validParams := []string{"filter", "All_fields", "Fields", "Exclude_fields", "Exclude_default"} err := validateQueryParams(q, validParams) if err != nil { print("Query Parameter error") errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) return } // Parse query parameters filters := q.Get("filter") allFields := q.Get("all_fields") // field := q["fields"] // excludeFields := q["exclude_fields"] // excludeDefault := q.Get("exclude_default") regInfoList := &RegisterationInfoList{ Filters: &FilterParameters{ filter: filters, all_fields: allFields, }, Registrations: make([]RegistrationInfo, 0), } // Get all AMS Registration Info regInfoList := make([]RegistrationInfo, 0) //regInfoList := make([]RegistrationInfo, 0) key := baseKey + "svc:*:info" err := rc.ForEachJSONEntry(key, populateRegInfoList, ®InfoList) err = rc.ForEachJSONEntry(key, populateRegInfoList, regInfoList) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) return } // Send response jsonResponse, err := json.Marshal(regInfoList) // Prepare & send response jsonResponse, err := json.Marshal(regInfoList.Registrations) if err != nil { log.Error(err.Error()) errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) Loading @@ -1498,21 +1541,275 @@ func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) { } func populateRegInfoList(key string, jsonEntry string, response interface{}) error { regInfoList := response.(*[]RegistrationInfo) if regInfoList == nil { return errors.New("Response not defined") data := response.(*RegisterationInfoList) if data == nil { return errors.New("response not defined") } // Retrieve registration info from DB var regInfo RegistrationInfo err := json.Unmarshal([]byte(jsonEntry), ®Info) println("keysss", key) if err != nil { return err } *regInfoList = append(*regInfoList, regInfo) // Filter services if data.Filters != nil { if data.Filters.filter != "" { filterField := data.Filters.filter // Split filterField into operator, attribute, and value filterField = strings.Trim(filterField, "()") filterParts := strings.SplitN(filterField, ",", 3) if len(filterParts) != 3 { return nil } operator := filterParts[0] attribute := filterParts[1] value := filterParts[2] // Apply filters based on attribute switch attribute { case "appMobilityServiceId": if !applyStringFilter(operator, regInfo.AppMobilityServiceId, value) { return nil } case "serviceConsumerId.appInstanceId": if !applyStringFilter(operator, regInfo.ServiceConsumerId.AppInstanceId, value) { return nil } case "serviceConsumerId.mepId": if !applyStringFilter(operator, regInfo.ServiceConsumerId.MepId, value) { return nil } case "deviceInformation.associateId": matched := false for _, deviceInfo := range regInfo.DeviceInformation { if applyStringFilter(operator, deviceInfo.AssociateId.Value, value) { matched = true break } } if !matched { return nil } // case "deviceInformation.contextTransferState": // matched := false // for _, deviceInfo := range regInfo.DeviceInformation { // if applyEnumFilter(operator, string(deviceInfo.ContextTransferState.val), value) { // matched = true // break // } // } // if !matched { // return fmt.Errorf("filter mismatch: deviceInformation.contextTransferState") // } case "expiryTime": expiryTime, err := strconv.ParseUint(value, 10, 32) if err != nil { return nil } if !applyNumericFilter(operator, uint32(regInfo.ExpiryTime), uint32(expiryTime)) { return nil } default: return nil } } } data.Registrations = append(data.Registrations, regInfo) return nil } // Helper functions for applying filters func applyStringFilter(operator, fieldValue, filterValue string) bool { switch operator { case "eq": return fieldValue == filterValue case "neq": return fieldValue != filterValue case "cont": return strings.Contains(fieldValue, filterValue) case "ncont": return !strings.Contains(fieldValue, filterValue) case "in": values := strings.Split(filterValue, ",") for _, v := range values { if fieldValue == v { return true } } return false case "nin": values := strings.Split(filterValue, ",") for _, v := range values { if fieldValue == v { return false } } return true case "gt": return fieldValue > filterValue case "gte": return fieldValue >= filterValue case "lt": return fieldValue < filterValue case "lte": return fieldValue <= filterValue default: return false } } func applyEnumFilter(operator, fieldValue, filterValue string) bool { return applyStringFilter(operator, fieldValue, filterValue) } func applyNumericFilter(operator string, fieldValue, filterValue uint32) bool { switch operator { case "eq": return fieldValue == filterValue case "neq": return fieldValue != filterValue case "gt": return fieldValue > filterValue case "gte": return fieldValue >= filterValue case "lt": return fieldValue < filterValue case "lte": return fieldValue <= filterValue default: return false } } // Original // func populateRegInfoList(key string, jsonEntry string, response interface{}) error { // data := response.(*RegisterationInfoList) // if data == nil { // return errors.New("response not defined") // } // // Retrieve registration info from DB // var regInfo RegistrationInfo // err := json.Unmarshal([]byte(jsonEntry), ®Info) // println("keysss", key) // if err == nil { // return err // } // // Filter services // if data.Filters != nil { // if data.Filters.filter != "" { // filterField := data.Filters.filter // if regInfo.AppMobilityServiceId == "" || (filterField != regInfo.AppMobilityServiceId) { // return nil // } // } // } // data.Registrations = append(data.Registrations, regInfo) // return nil // } // filterRegistrationInfo applies filtering based on the provided filters. // func filterRegistrationInfo(regInfoList []RegistrationInfo, filters []string) []RegistrationInfo { // var filteredList []RegistrationInfo // for _, regInfo := range regInfoList { // match := true // // Iterate over filters to apply them one by one // for _, filter := range filters { // filterParts := strings.Split(filter, ":") // if len(filterParts) != 2 { // // Invalid filter format (e.g., "key:value") // continue // } // key := filterParts[0] // value := filterParts[1] // // Apply filter based on key-value pairs // switch key { // case "appMobilityServiceId": // if regInfo.AppMobilityServiceId != value { // match = false // } // case "appInstanceId": // if regInfo.ServiceConsumerId.AppInstanceId != value { // match = false // } // case "mepId": // if regInfo.ServiceConsumerId.MepId != value { // match = false // } // case "associateId": // // Check if any device has the associateId value // found := false // for _, device := range regInfo.DeviceInformation { // if device.AssociateId == value { // found = true // break // } // } // if !found { // match = false // } // case "expiryTime": // expiryTime, err := strconv.Atoi(value) // if err != nil || regInfo.ExpiryTime != uint32(expiryTime) { // match = false // } // default: // // If filter key is not recognized, skip it // continue // } // // If any filter condition doesn't match, we stop checking further // if !match { // break // } // } // // If all filters matched, add to the result list // if match { // filteredList = append(filteredList, regInfo) // } // } // return filteredList // } // func populateRegInfoList(key string, jsonEntry string, response interface{}) error { // regInfoList := response.(*[]RegistrationInfo) // if regInfoList == nil { // return errors.New("Response not defined") // } // // Retrieve registration info from DB // var regInfo RegistrationInfo // err := json.Unmarshal([]byte(jsonEntry), ®Info) // if err != nil { // return err // } // *regInfoList = append(*regInfoList, regInfo) // return nil // } func cleanUp() { log.Info("Terminate all") Loading Loading @@ -2324,21 +2621,22 @@ func delTrackedDevInfo(svcId string, address string) error { return nil } func validateQueryParams(params url.Values, validParamList []string) bool { func validateQueryParams(params url.Values, validParams []string) error { for param := range params { found := false for _, validParam := range validParamList { for _, validParam := range validParams { if param == validParam { found = true break } } if !found { log.Error("Invalid query param: ", param) return false err := errors.New("Invalid query param: " + param) log.Error(err.Error()) return err } } return true return nil } func validateQueryParamValue(val string, validValues []string) bool { Loading