Commit 3d8f80a9 authored by Dimitris Fragkos's avatar Dimitris Fragkos
Browse files

include net-slice-info query in GET /discover request

parent 12f89e33
Loading
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -103,9 +103,31 @@ def all_service_apis_get(api_invoker_id, api_name=None, api_version=None, comm_t
    """
    current_app.logger.debug("Discovering service apis")

    if net_slice_info is None:
        if "net-slice-info" in request.args:
            raw_net_slice_info = request.args.get("net-slice-info")
            try:
                net_slice_info = json.loads(raw_net_slice_info)
            except (json.JSONDecodeError, TypeError) as e:
                current_app.logger.warning(
                    "Failed to parse net-slice-info query parameter: %s. Raw value: %s",
                    str(e),
                    raw_net_slice_info
                )

        elif "net-slice-info.snssai.sst" in request.args:
            net_slice_info = [{
                "snssai": {
                    "sst": int(request.args.get("net-slice-info.snssai.sst")),
                    "sd": request.args.get("net-slice-info.snssai.sd")
                }
            }]
            current_app.logger.debug("Parsed dotted net-slice-info: %s", net_slice_info)

    query_params = {"api_name": api_name, "api_version": api_version, "comm_type": comm_type,
                    "protocol": protocol, "aef_id": aef_id, "data_format": data_format,
                    "api_cat": api_cat, "api_supported_features": api_supported_features,
                    "net_slice_info": net_slice_info,
                    "supported_features": supported_features}

    if supported_features is not None:
+80 −2
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ import json
from flask import current_app

from ..core.resources import Resource
from ..core.responses import (internal_server_error, make_response,
from ..core.responses import (bad_request_error, internal_server_error, make_response,
                              not_found_error)
from ..models.discovered_apis import DiscoveredAPIs
from ..util import serialize_clean_camel_case
@@ -16,6 +16,10 @@ TOTAL_FEATURES = 4
SUPPORTED_FEATURES_HEX = "2"


class NetSliceInfoValidationError(Exception):
    pass


def filter_fields(filtered_apis):
    key_filter = [
        "api_name", "api_id", "aef_profiles", "description",
@@ -41,6 +45,68 @@ def return_negotiated_supp_feat_dict(supp_feat):
    }


def _normalize_net_slice_info(net_slice_info):
    if net_slice_info is None:
        return []

    if isinstance(net_slice_info, str):
        try:
            net_slice_info = json.loads(net_slice_info)
        except json.JSONDecodeError:
            return []

    if isinstance(net_slice_info, dict):
        net_slice_info = [net_slice_info]

    normalized = []
    for net_slice in net_slice_info:
        if isinstance(net_slice, dict):
            normalized.append(net_slice)
        elif hasattr(net_slice, "to_dict"):
            normalized.append(net_slice.to_dict())

    return normalized


def _build_net_slice_info_query(net_slice_info):
    normalized = _normalize_net_slice_info(net_slice_info)
    if not normalized:
        return None

    net_slice_elem_matches = []
    for net_slice in normalized:
        elem_match = {}

        if net_slice.get("nsi_id") is not None:
            elem_match["nsi_id"] = net_slice["nsi_id"]
        elif net_slice.get("nsiId") is not None:
            elem_match["nsi_id"] = net_slice["nsiId"]

        if net_slice.get("ensi") is not None:
            elem_match["ensi"] = net_slice["ensi"]

        snssai = net_slice.get("snssai")
        if isinstance(snssai, dict):
            if snssai.get("sd") is not None and snssai.get("sst") is None:
                raise NetSliceInfoValidationError("snssai.sd requires snssai.sst")

            snssai_match = {}
            if snssai.get("sst") is not None:
                snssai_match["sst"] = snssai["sst"]
            if snssai.get("sd") is not None:
                snssai_match["sd"] = snssai["sd"]
            if snssai_match:
                elem_match["snssai"] = snssai_match

        if elem_match:
            net_slice_elem_matches.append({"net_slice_info": {"$elemMatch": elem_match}})

    if not net_slice_elem_matches:
        return None

    return {"$or": net_slice_elem_matches}


class DiscoverApisOperations(Resource):

    def get_discoveredapis(self, api_invoker_id, query_params):
@@ -68,7 +134,8 @@ class DiscoverApisOperations(Resource):
                "data_format": '{"aef_profiles": {"$elemMatch": {"data_format":"QPV"}}}',
                "api_cat": "service_api_category",
                "supported_features": "supported_features",
                "api_supported_features": "api_supp_feats"
                "api_supported_features": "api_supp_feats",
                "net_slice_info": "net_slice_info"
            }

            vend_spec_query_params_n_values = {}
@@ -81,6 +148,10 @@ class DiscoverApisOperations(Resource):
                        vend_param = param.split("vend-spec-")[1]
                        attribute_path = query_params[param]["target"].split('/')
                        vend_spec_query_params_n_values[".".join(attribute_path[1:]) + "." + vend_param] = query_params[param]["value"]
                    elif param == "net_slice_info":
                        net_slice_info_query = _build_net_slice_info_query(query_params[param])
                        if net_slice_info_query is not None:
                            my_params.append(net_slice_info_query)
                    elif param in ["api_version", "comm_type", "protocol", "aef_id", "data_format"]:
                        my_params.append(json.loads(query_params_name[param].replace("QPV", query_params[param])))
                    else:
@@ -121,6 +192,13 @@ class DiscoverApisOperations(Resource):
            res = make_response(object=serialize_clean_camel_case(apis_discovered), status=200)
            return res

        except NetSliceInfoValidationError as e:
            return bad_request_error(
                detail="Invalid net-slice-info query parameter",
                cause=str(e),
                invalid_params=[{"param": "net-slice-info", "reason": str(e)}]
            )

        except Exception as e:
            exception = "An exception occurred in discover services"
            current_app.logger.error(exception + "::" + str(e))