Loading services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +81 −5 Original line number Original line Diff line number Diff line Loading @@ -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] Loading Loading @@ -122,19 +147,30 @@ 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 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( Loading @@ -155,7 +191,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") Loading Loading @@ -311,6 +347,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: Loading Loading @@ -400,6 +456,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: Loading Loading
services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +81 −5 Original line number Original line Diff line number Diff line Loading @@ -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] Loading Loading @@ -122,19 +147,30 @@ 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 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( Loading @@ -155,7 +191,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") Loading Loading @@ -311,6 +347,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: Loading Loading @@ -400,6 +456,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: Loading