Commit 87bf585a authored by Jorge Moratinos's avatar Jorge Moratinos
Browse files

Merge branch 'OCF204-same-apiname-between-different-apis-must-be-allowed' into 'staging'

Ocf204 same apiname between different apis must be allowed

See merge request !184
parents 4f57c532 4c8e8200
Loading
Loading
Loading
Loading
Loading
+82 −5
Original line number Original line Diff line number Diff line
@@ -24,6 +24,31 @@ publisher_ops = Publisher()


service_api_not_found_message = "Service API not found"
service_api_not_found_message = "Service API not found"


def find_duplicate_service_by_api_name_and_aef(
        collection,
        api_name,
        aef_profiles,
        excluded_api_id=None):
    duplicate_query = {"api_name": api_name}
    aef_ids = set()
    for profile in aef_profiles or []:
        if isinstance(profile, dict):
            aef_id = profile.get("aef_id")
        else:
            aef_id = getattr(profile, "aef_id", None)

        if aef_id:
            aef_ids.add(aef_id)

    aef_ids = sorted(aef_ids)

    if aef_ids:
        duplicate_query["aef_profiles.aef_id"] = {"$in": aef_ids}
    if excluded_api_id:
        duplicate_query["api_id"] = {"$ne": excluded_api_id}

    return collection.find_one(duplicate_query), aef_ids



def return_negotiated_supp_feat_dict(supp_feat):
def return_negotiated_supp_feat_dict(supp_feat):
    final_supp_feat = bin(int(supp_feat, 16) & int(SUPPORTED_FEATURES_HEX, 16))[2:].zfill(TOTAL_FEATURES)[::-1]
    final_supp_feat = bin(int(supp_feat, 16) & int(SUPPORTED_FEATURES_HEX, 16))[2:].zfill(TOTAL_FEATURES)[::-1]
@@ -122,19 +147,31 @@ class PublishServiceOperations(Resource):
        try:
        try:
            current_app.logger.debug("Publishing service")
            current_app.logger.debug("Publishing service")


            service = mycol.find_one(
            serviceapidescription_dict = serviceapidescription.to_dict()
                {"api_name": serviceapidescription.api_name})
            service, aef_ids = find_duplicate_service_by_api_name_and_aef(
                mycol,
                serviceapidescription.api_name,
                serviceapidescription_dict.get("aef_profiles"))
            if service is not None:
            if service is not None:
                if aef_ids:
                    current_app.logger.error(
                        "Service already registered with same api_name/aef_id pair")
                    return forbidden_error(
                        detail="Already registered service with same api name and aef id",
                        cause="Found service with same api name and aef id")

                current_app.logger.error(
                current_app.logger.error(
                    "Service already registered with same api name")
                    "Service already registered with same api name")
                return forbidden_error(detail="Already registered service with same api name", cause="Found service with same api name")
                return forbidden_error(
                    detail="Already registered service with same api name",
                    cause="Found service with same api name")


            api_id = secrets.token_hex(15)
            api_id = secrets.token_hex(15)
            serviceapidescription.api_id = api_id
            serviceapidescription.api_id = api_id
            serviceapidescription_dict["api_id"] = api_id
            rec = dict()
            rec = dict()
            rec['apf_id'] = apf_id
            rec['apf_id'] = apf_id
            rec['onboarding_date'] = datetime.now()
            rec['onboarding_date'] = datetime.now()
            serviceapidescription_dict = serviceapidescription.to_dict()


            if vendor_specific:
            if vendor_specific:
                serviceapidescription_dict = add_vend_spec_fields(
                serviceapidescription_dict = add_vend_spec_fields(
@@ -155,7 +192,7 @@ class PublishServiceOperations(Resource):


            res = make_response(object=clean_n_camel_case(
            res = make_response(object=clean_n_camel_case(
                serviceapidescription_dict), status=201)
                serviceapidescription_dict), status=201)
            res.headers['Location'] = f"https://{os.getenv("CAPIF_HOSTNAME")}/published-apis/v1/{str(apf_id)}/service-apis/{str(api_id)}"
            res.headers['Location'] = f"https://{os.getenv('CAPIF_HOSTNAME')}/published-apis/v1/{str(apf_id)}/service-apis/{str(api_id)}"


            if res.status_code == 201:
            if res.status_code == 201:
                current_app.logger.info("Service published")
                current_app.logger.info("Service published")
@@ -311,6 +348,26 @@ class PublishServiceOperations(Resource):
            service_api_description["apf_id"] = serviceapidescription_old["apf_id"]
            service_api_description["apf_id"] = serviceapidescription_old["apf_id"]
            service_api_description["onboarding_date"] = serviceapidescription_old["onboarding_date"]
            service_api_description["onboarding_date"] = serviceapidescription_old["onboarding_date"]
            service_api_description["api_id"] = serviceapidescription_old["api_id"]
            service_api_description["api_id"] = serviceapidescription_old["api_id"]

            service_with_same_identity, aef_ids = find_duplicate_service_by_api_name_and_aef(
                mycol,
                service_api_description.get("api_name", serviceapidescription_old.get("api_name")),
                service_api_description.get("aef_profiles", serviceapidescription_old.get("aef_profiles")),
                excluded_api_id=service_api_description["api_id"])
            if service_with_same_identity is not None:
                if aef_ids:
                    current_app.logger.error(
                        "Service already registered with same api_name/aef_id pair")
                    return forbidden_error(
                        detail="Already registered service with same api name and aef id",
                        cause="Found service with same api name and aef id")

                current_app.logger.error(
                    "Service already registered with same api name")
                return forbidden_error(
                    detail="Already registered service with same api name",
                    cause="Found service with same api name")

            service_api_description["supported_features"] = return_negotiated_supp_feat_dict(service_api_description["supported_features"])["Final"]
            service_api_description["supported_features"] = return_negotiated_supp_feat_dict(service_api_description["supported_features"])["Final"]


            if not return_negotiated_supp_feat_dict(service_api_description.get("supported_features"))["ApiStatusMonitoring"] and service_api_description.get("api_status", None) is not None:
            if not return_negotiated_supp_feat_dict(service_api_description.get("supported_features"))["ApiStatusMonitoring"] and service_api_description.get("api_status", None) is not None:
@@ -400,6 +457,26 @@ class PublishServiceOperations(Resource):
            api_status = patch_service_api_description.get("api_status", None)
            api_status = patch_service_api_description.get("api_status", None)
            supported_features = patch_service_api_description.get("supported_features", None)
            supported_features = patch_service_api_description.get("supported_features", None)
            patch_service_api_description = clean_empty(patch_service_api_description)
            patch_service_api_description = clean_empty(patch_service_api_description)

            service_with_same_identity, aef_ids = find_duplicate_service_by_api_name_and_aef(
                mycol,
                serviceapidescription_old.get("api_name"),
                patch_service_api_description.get("aef_profiles", serviceapidescription_old.get("aef_profiles")),
                excluded_api_id=serviceapidescription_old.get("api_id"))
            if service_with_same_identity is not None:
                if aef_ids:
                    current_app.logger.error(
                        "Service already registered with same api_name/aef_id pair")
                    return forbidden_error(
                        detail="Already registered service with same api name and aef id",
                        cause="Found service with same api name and aef id")

                current_app.logger.error(
                    "Service already registered with same api name")
                return forbidden_error(
                    detail="Already registered service with same api name",
                    cause="Found service with same api name")

            if api_status:
            if api_status:
                patch_service_api_description["api_status"]=api_status
                patch_service_api_description["api_status"]=api_status
            if supported_features:
            if supported_features: