Commit 0247cad7 authored by Stavros Charismiadis's avatar Stavros Charismiadis
Browse files

fix vendor extensibility issues

parent c8c610a5
Loading
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -68,12 +68,14 @@ def all_service_apis_get(api_invoker_id, api_name=None, api_version=None, comm_t
    if request.is_json:
        service_kpis = ServiceKpis.from_dict(request.get_json()())  # noqa: E501
    current_app.logger.info("Discovering service apis")
    # supported_features was removed from query_params
    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, "supported_features":supported_features, "api_supported_features":api_supported_features}
                    "api_cat": api_cat, "api_supported_features": api_supported_features}

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


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

            vend_spec_query_params_n_values = {}
            for param in query_params:
                current_app.logger.info(query_params[param])
                if query_params[param] is not None:
                    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 = "aef_profiles.0." + attribute_path[1] + "." + attribute_path[2]
                        my_params.append({attribute: query_params[param]["value"]})
                        vend_spec_query_params_n_values[attribute_path[1] + "." + vend_param] = query_params[param]["value"]
                    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])))
                    else:
                        my_params.append({query_params_name[param]: query_params[param]})
@@ -55,9 +53,13 @@ class DiscoverApisOperations(Resource):
            if 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 = []
            for discoved_api in discoved_apis:
                vendor_specific_fields_path = find_attribute_in_body(discoved_api, '')
                if vend_spec_query_params_n_values and vendor_specific_fields_path:
                    json_docs.append(filter_apis_with_vendor_specific_params(discoved_api, vend_spec_query_params_n_values, vendor_specific_fields_path))
                else:
                    json_docs.append(discoved_api)

            if len(json_docs) == 0:
+4 −3
Original line number Diff line number Diff line
@@ -32,13 +32,14 @@ class DiscoveredAPIs(Model):

    @classmethod
    def return_supp_feat_dict(cls, supp_feat):
        TOTAL_FEATURES = 3
        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 {
            "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,
            "ApiSupportedFeatureQuery": True if supp_feat_in_bin[2] == "1" else False,
            "RNAA": True if supp_feat_in_bin[2] == "1" else False
        }

    @classmethod
+76 −0
Original line number 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 filter_apis_with_vendor_specific_params(discoved_api, vend_spec_query_params_n_values, vendor_specific_fields_path):
    json_docs = []
    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
                # Check if parameter exists in the field attributes!!!!
                if tmp_body[vs_field][parts[1]] == v:
                    json_docs.append(discoved_api)
                else:
                    continue
    return json_docs
 No newline at end of file
+3 −5
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ from cryptography.hazmat.backends import default_backend
from ..core.validate_user import ControlAccess
from functools import wraps
import asyncio
from published_apis.vendor_specific import vendor_specific_key_n_value, find_attribute_in_body


service_operations = PublishServiceOperations()
@@ -82,11 +83,8 @@ def apf_id_service_apis_post(apf_id, body): # noqa: E501
    vendor_specific = []
    if request.is_json:
        if supp_feat_dict['VendorExt']:
            aef_profile_array = body['aefProfiles']
            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))
            vendor_specific_fields = find_attribute_in_body(body, '')
            vendor_specific = vendor_specific_key_n_value(vendor_specific_fields, body)

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

Loading