Commit 9b544ad2 authored by Pelayo Torres's avatar Pelayo Torres
Browse files

Merge branch 'staging' into OCF88-fix-enhanced-event-report

parents 79cbeb6a 56b8791a
Loading
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -68,12 +68,15 @@ def all_service_apis_get(api_invoker_id, api_name=None, api_version=None, comm_t
    if request.is_json:
    if request.is_json:
        service_kpis = ServiceKpis.from_dict(request.get_json()())  # noqa: E501
        service_kpis = ServiceKpis.from_dict(request.get_json()())  # noqa: E501
    current_app.logger.info("Discovering service apis")
    current_app.logger.info("Discovering service apis")

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


    if supported_features is not None:
    if supported_features is not None:
        supp_feat_dict = DiscoveredAPIs.return_supp_feat_dict(supported_features)
        supp_feat_dict = DiscoveredAPIs.return_supp_feat_dict(supported_features)
        current_app.logger.info(supp_feat_dict)
        if supp_feat_dict['VendSpecQueryParams']:
        if supp_feat_dict['VendSpecQueryParams']:
            for q_params in request.args:
            for q_params in request.args:
                if "vend-spec" in q_params:
                if "vend-spec" in q_params:
+42 −9
Original line number Original line Diff line number Diff line
@@ -5,6 +5,20 @@ from ..models.discovered_apis import DiscoveredAPIs
from ..util import serialize_clean_camel_case
from ..util import serialize_clean_camel_case
from ..core.resources import Resource
from ..core.resources import Resource
import json
import json
from ..vendor_specific import find_attribute_in_body, filter_apis_with_vendor_specific_params, remove_vendor_specific_fields


def filter_fields(filtered_apis):
    key_filter = [
        "api_name", "api_id", "aef_profiles", "description",
        "supported_features", "shareable_info", "service_api_category",
        "api_supp_feats", "pub_api_path", "ccf_id"
    ]
    field_filtered_api = {}
    for key in filtered_apis.keys():
        if key in key_filter or 'vendorSpecific' in key:
            field_filtered_api[key] = filtered_apis[key]
    return field_filtered_api




class DiscoverApisOperations(Resource):
class DiscoverApisOperations(Resource):
@@ -37,17 +51,17 @@ class DiscoverApisOperations(Resource):
                "api_supported_features": "api_supp_feats"
                "api_supported_features": "api_supp_feats"
            }
            }


            vend_spec_query_params_n_values = {}
            supp_feat = query_params["supported_features"]
            del query_params["supported_features"]

            for param in query_params:
            for param in query_params:
                current_app.logger.info(query_params[param])
                if query_params[param] is not None:
                if query_params[param] is not None:
                    if "vend-spec" in param:
                    if "vend-spec" in param:
                        current_app.logger.info("vend-spec in param")
                        vend_param = param.split("vend-spec-")[1]
                        attribute_path = query_params[param]["target"].split('/')
                        attribute_path = query_params[param]["target"].split('/')
                        attribute = "aef_profiles.0." + attribute_path[1] + "." + attribute_path[2]
                        vend_spec_query_params_n_values[attribute_path[1] + "." + vend_param] = query_params[param]["value"]
                        my_params.append({attribute: query_params[param]["value"]})
                    elif param in ["api_version", "comm_type", "protocol", "aef_id", "data_format"]:
                    elif param in ["api_version", "comm_type", "protocol", "aef_id", "data_format"]:
                        current_app.logger.info(query_params_name[param])
                        current_app.logger.info(query_params_name[param].replace("QPV", query_params[param]))
                        my_params.append(json.loads(query_params_name[param].replace("QPV", query_params[param])))
                        my_params.append(json.loads(query_params_name[param].replace("QPV", query_params[param])))
                    else:
                    else:
                        my_params.append({query_params_name[param]: query_params[param]})
                        my_params.append({query_params_name[param]: query_params[param]})
@@ -55,10 +69,29 @@ class DiscoverApisOperations(Resource):
            if my_params:
            if my_params:
                my_query = {"$and": my_params}
                my_query = {"$and": my_params}


            discoved_apis = services.find(my_query, {"_id":0, "api_name":1, "api_id":1, "aef_profiles":1, "description":1, "supported_features":1, "shareable_info":1, "service_api_category":1, "api_supp_feats":1, "pub_api_path":1, "ccf_id":1})
            discoved_apis = services.find(my_query, {"_id":0})
            json_docs = []
            json_docs = []
            if supp_feat is None:
                for discoved_api in discoved_apis:
                    vendor_specific_fields_path = find_attribute_in_body(discoved_api, '')
                    json_docs.append(filter_fields(remove_vendor_specific_fields(discoved_api, vendor_specific_fields_path)))
            else:
                supported_features = DiscoveredAPIs.return_supp_feat_dict(supp_feat)
                if supported_features['VendSpecQueryParams']:
                    for discoved_api in discoved_apis:
                        vendor_specific_fields_path = find_attribute_in_body(discoved_api, '')
                        if vendor_specific_fields_path:
                            if vend_spec_query_params_n_values:
                                vs_filtered_apis = filter_apis_with_vendor_specific_params(discoved_api, vend_spec_query_params_n_values, vendor_specific_fields_path)
                                if vs_filtered_apis:
                                    json_docs.append(filter_fields(vs_filtered_apis))
                            else:
                                json_docs.append(filter_fields(discoved_api))
                else:
                    for discoved_api in discoved_apis:
                    for discoved_api in discoved_apis:
                json_docs.append(discoved_api)
                        vendor_specific_fields_path = find_attribute_in_body(discoved_api, '')
                        if not vendor_specific_fields_path:
                            json_docs.append(filter_fields(discoved_api))


            if len(json_docs) == 0:
            if len(json_docs) == 0:
                return not_found_error(detail="API Invoker " + api_invoker_id + " has no API Published that accomplish filter conditions", cause="No API Published accomplish filter conditions")
                return not_found_error(detail="API Invoker " + api_invoker_id + " has no API Published that accomplish filter conditions", cause="No API Published accomplish filter conditions")
+4 −3
Original line number Original line Diff line number Diff line
@@ -32,13 +32,14 @@ class DiscoveredAPIs(Model):


    @classmethod
    @classmethod
    def return_supp_feat_dict(cls, supp_feat):
    def return_supp_feat_dict(cls, supp_feat):
        TOTAL_FEATURES = 3
        supp_feat_in_hex = int(supp_feat, 16)
        supp_feat_in_hex = int(supp_feat, 16)
        supp_feat_in_bin = bin(supp_feat_in_hex)[2:]
        supp_feat_in_bin = bin(supp_feat_in_hex)[2:].zfill(TOTAL_FEATURES)[::-1]


        return {
        return {
            "RNAA": True if supp_feat_in_bin[0] == "1" else False,
            "ApiSupportedFeatureQuery": True if supp_feat_in_bin[0] == "1" else False,
            "VendSpecQueryParams": True if supp_feat_in_bin[1] == "1" else False,
            "VendSpecQueryParams": True if supp_feat_in_bin[1] == "1" else False,
            "ApiSupportedFeatureQuery": True if supp_feat_in_bin[2] == "1" else False,
            "RNAA": True if supp_feat_in_bin[2] == "1" else False
        }
        }


    @classmethod
    @classmethod
+91 −0
Original line number Original line Diff line number Diff line
import re


def find_attribute_in_body(test, path):
    f_key = []
    if type(test) == dict:
        for k, v in test.items():
            if 'vendorSpecific' in k:
                if path == '':
                    temp_path = k
                else:
                    temp_path = path + "." + k
                f_key.append(temp_path)
            elif type(v) == dict:
                if path == '':
                    temp_path = k
                else:
                    temp_path = path + "." + k
                f_key += find_attribute_in_body(v, temp_path)
            elif type(v) == list:
                if path == '':
                    temp_path = k
                else:
                    temp_path = path + "." + k
                for i, val in enumerate(v):
                    f_key += find_attribute_in_body(val, temp_path + "." +  str(i))
    return f_key


def vendor_specific_key_n_value(vendor_specific_fields, body):
    vendor_specific = {}
    for field in vendor_specific_fields:
        parts = field.split('.')
        tmp_body = body
        for part in parts:
            if part.isnumeric():
                part = int(part)
            v = tmp_body[part]
            tmp_body = v
        vendor_specific[field] = v
    return vendor_specific


def add_vend_spec_fields(vendor_specific, serviceapidescription_dict):
    pattern = re.compile(r'(?<!^)(?=[A-Z])')
    for field, value in vendor_specific.items():
        parts = field.split('.')
        tmp_body = serviceapidescription_dict
        vs_field = parts[-1]
        for part in parts[:-1]:
            if part.isnumeric():
                part = int(part)
            else:
                part = pattern.sub('_', part).lower()
            tmp_body = tmp_body[part]
        tmp_body[vs_field] = value
    return tmp_body


def remove_vendor_specific_fields(discoved_api, vendor_specific_fields_path):
    for path in vendor_specific_fields_path:
        tmp_body = discoved_api
        parts = path.split('.')
        vs_field = parts[-1]
        for path_piece in parts[:-1]:
            if path_piece.isnumeric():
                path_piece = int(path_piece)
            tmp_body = tmp_body[path_piece]
        del tmp_body[vs_field]
    return discoved_api


def filter_apis_with_vendor_specific_params(discoved_api, vend_spec_query_params_n_values, vendor_specific_fields_path):
    for k, v in vend_spec_query_params_n_values.items():
        parts = k.split('.')
        for path in vendor_specific_fields_path:
            if parts[0] in path:
                path_pieces = path.split('.')
                tmp_body = discoved_api
                vs_field = path_pieces[-1]
                for path_piece in path_pieces[:-1]:
                    if path_piece.isnumeric():
                        path_piece = int(path_piece)
                    v_2 = tmp_body[path_piece]
                    tmp_body = v_2
                if parts[1] in tmp_body[vs_field].keys():
                    if tmp_body[vs_field][parts[1]] != v:
                        return {}
                else:
                    return {}
    return discoved_api
 No newline at end of file
+20 −6
Original line number Original line Diff line number Diff line
@@ -7,6 +7,9 @@ from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.backends import default_backend
from ..core.validate_user import ControlAccess
from ..core.validate_user import ControlAccess
from functools import wraps
from functools import wraps
from published_apis.vendor_specific import vendor_specific_key_n_value, find_attribute_in_body
from ..core.responses import bad_request_error



service_operations = PublishServiceOperations()
service_operations = PublishServiceOperations()


@@ -82,18 +85,29 @@ def apf_id_service_apis_post(apf_id, body): # noqa: E501
    """
    """
    current_app.logger.info("Publishing service")
    current_app.logger.info("Publishing service")


    if 'supportedFeatures' not in body:
        return bad_request_error(
            detail="supportedFeatures not present in request",
            cause="supportedFeatures not present",
            invalid_params=[{"param": "supportedFeatures", "reason": "not defined"}]
        )

    supp_feat_dict = ServiceAPIDescription.return_supp_feat_dict(
    supp_feat_dict = ServiceAPIDescription.return_supp_feat_dict(
        body['supportedFeatures'])
        body['supportedFeatures'])


    vendor_specific = []
    vendor_specific = []
    vendor_specific_fields = find_attribute_in_body(body, '')

    if supp_feat_dict['VendorExt'] ^ bool(vendor_specific_fields):
        return bad_request_error(
            detail="If and only if VendorExt feature is enabled, then vendor-specific fields should be defined",
            cause="Vendor extensibility misconfiguration",
            invalid_params=[{"param": "vendor extensibility", "reason": "wrong definition"}]
        )

    if request.is_json:
    if request.is_json:
        if supp_feat_dict['VendorExt']:
        if supp_feat_dict['VendorExt']:
            aef_profile_array = body['aefProfiles']
            vendor_specific = vendor_specific_key_n_value(vendor_specific_fields, body)
            for (profile, i) in zip(aef_profile_array, range(len(aef_profile_array))):
                for key, val in profile.items():
                    if 'vendorSpecific' in key:
                        vendor_specific.append((i, key, val))

        body = ServiceAPIDescription.from_dict(request.get_json())
        body = ServiceAPIDescription.from_dict(request.get_json())


    res = service_operations.add_serviceapidescription(
    res = service_operations.add_serviceapidescription(
Loading