diff --git a/go-apps/meep-ams/server/ams.go b/go-apps/meep-ams/server/ams.go index fd9d98c8f4a0f929dac88e10e3cce942a3016e3b..e6c3d23452c7c0f0f210394342baf5276cb2eb14 100644 --- a/go-apps/meep-ams/server/ams.go +++ b/go-apps/meep-ams/server/ams.go @@ -28,6 +28,7 @@ import ( "net/http" "net/url" "os" + "regexp" "sort" "strconv" "strings" @@ -1488,6 +1489,7 @@ 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 @@ -1502,16 +1504,17 @@ func appMobilityServiceGET(w http.ResponseWriter, r *http.Request) { } // Parse query parameters - filters := q.Get("filter") - allFields := q.Get("all_fields") + urlFilter := q.Get("filter") + // allFields := q.Get("all_fields") // field := q["fields"] // excludeFields := q["exclude_fields"] // excludeDefault := q.Get("exclude_default") - + if urlFilter != "" { + fmt.Printf("filter: %s", urlFilter) + } regInfoList := &RegisterationInfoList{ Filters: &FilterParameters{ - filter: filters, - all_fields: allFields, + filter: urlFilter, }, Registrations: make([]RegistrationInfo, 0), } @@ -1549,7 +1552,6 @@ func populateRegInfoList(key string, jsonEntry string, response interface{}) err // Retrieve registration info from DB var regInfo RegistrationInfo err := json.Unmarshal([]byte(jsonEntry), ®Info) - println("keysss", key) if err != nil { return err } @@ -1557,18 +1559,25 @@ func populateRegInfoList(key string, jsonEntry string, response interface{}) err // Filter services if data.Filters != nil { + // Filter Paramter if data.Filters.filter != "" { filterField := data.Filters.filter + fmt.Printf("Filter Field: %s", filterField) // 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] + operator, attribute, value, _ := parseFilter(string(filterField)) + + fmt.Printf("operator: %s", operator) + fmt.Printf("attribute: %s", attribute) + fmt.Printf("value: %s", 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 { @@ -1577,17 +1586,17 @@ func populateRegInfoList(key string, jsonEntry string, response interface{}) err return nil } - case "serviceConsumerId.appInstanceId": + case "serviceConsumerId/appInstanceId": if !applyStringFilter(operator, regInfo.ServiceConsumerId.AppInstanceId, value) { return nil } - case "serviceConsumerId.mepId": + case "serviceConsumerId/mepId": if !applyStringFilter(operator, regInfo.ServiceConsumerId.MepId, value) { return nil } - case "deviceInformation.associateId": + case "deviceInformation/associateId": matched := false for _, deviceInfo := range regInfo.DeviceInformation { if applyStringFilter(operator, deviceInfo.AssociateId.Value, value) { @@ -1599,17 +1608,17 @@ func populateRegInfoList(key string, jsonEntry string, response interface{}) err 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 "deviceInformation/contextTransferState": + matched := false + for _, deviceInfo := range regInfo.DeviceInformation { + if applyEnumFilter(operator, string(*deviceInfo.ContextTransferState), value) { + matched = true + break + } + } + if !matched { + return nil + } case "expiryTime": expiryTime, err := strconv.ParseUint(value, 10, 32) @@ -1631,185 +1640,6 @@ func populateRegInfoList(key string, jsonEntry string, response interface{}) err 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") @@ -2668,3 +2498,92 @@ func errHandlerProblemDetails(w http.ResponseWriter, error string, code int) { w.WriteHeader(code) fmt.Fprint(w, jsonResponse) } + +func parseFilter(filterField string) (string, string, string, error) { + // Regular expression to match the filter format + re := regexp.MustCompile(`^(eq|neq|gt|lt|gte|lte|in|nin|cont|ncont),([a-zA-Z0-9/]+),([^,]+)(?:,([^,]+))?$`) + + // Trim any surrounding parentheses + filterField = strings.Trim(filterField, "()") + + // Match the filterField against the regular expression + matches := re.FindStringSubmatch(filterField) + if len(matches) < 3 { + return "", "", "", nil + } + + // Extract the operator, attribute, and value(s) + operator := matches[1] + attribute := matches[2] + value := matches[3] + + // If there's a second value (for operators like "in" or "nin"), handle it + if len(matches) > 4 && matches[4] != "" { + value += "," + matches[4] + } + + return operator, attribute, value, 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 + } +}