Loading services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py +7 −0 Original line number Original line Diff line number Diff line Loading @@ -173,6 +173,13 @@ def apf_id_service_apis_service_api_id_put(service_api_id, apf_id, body): # noq current_app.logger.info( current_app.logger.info( "Updating service api id with id: " + service_api_id) "Updating service api id with id: " + service_api_id) 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"}] ) if request.is_json: if request.is_json: body = ServiceAPIDescription.from_dict(request.get_json()) # noqa: E501 body = ServiceAPIDescription.from_dict(request.get_json()) # noqa: E501 Loading services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +75 −78 Original line number Original line Diff line number Diff line Loading @@ -132,28 +132,13 @@ class PublishServiceOperations(Resource): if res.status_code == 201: if res.status_code == 201: current_app.logger.info("Service published") current_app.logger.info("Service published") if serviceapidescription.api_status is None or len(serviceapidescription.api_status.aef_ids) > 0: event_to_send = self.service_api_availability_event( if serviceapidescription.return_supp_feat_dict(serviceapidescription.supported_features)["ApiStatusMonitoring"]: clean_n_camel_case( current_app.logger.info(f"Service available") serviceapidescription_dict)) RedisEvent("SERVICE_API_AVAILABLE", RedisEvent(event_to_send, service_api_descriptions=[clean_n_camel_case( service_api_descriptions=[clean_n_camel_case( serviceapidescription.to_dict())], serviceapidescription.to_dict())], api_ids=[str(api_id)]).send_event() api_ids=[str(api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_AVAILABLE", api_ids=[str(api_id)]).send_event() else: if serviceapidescription.return_supp_feat_dict(serviceapidescription.supported_features)["ApiStatusMonitoring"]: current_app.logger.info(f"Service unavailable") RedisEvent("SERVICE_API_UNAVAILABLE", service_api_descriptions=[clean_n_camel_case( serviceapidescription.to_dict())], api_ids=[str(api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_UNAVAILABLE", api_ids=[str(api_id)]).send_event() return res return res Loading Loading @@ -229,11 +214,6 @@ class PublishServiceOperations(Resource): serviceapidescription = clean_empty( serviceapidescription = clean_empty( dict_to_camel_case(serviceapidescription_dict)) dict_to_camel_case(serviceapidescription_dict)) if res.status_code == 204: if res.status_code == 204: is_supported = serviceapidescription.get("supportedFeatures") and \ ServiceAPIDescription.return_supp_feat_dict( serviceapidescription["supportedFeatures"]).get("ApiStatusMonitoring") if is_supported: current_app.logger.info("Service unavailable") current_app.logger.info("Service unavailable") RedisEvent( RedisEvent( "SERVICE_API_UNAVAILABLE", "SERVICE_API_UNAVAILABLE", Loading @@ -241,14 +221,6 @@ class PublishServiceOperations(Resource): api_ids=[str(service_api_id)] api_ids=[str(service_api_id)] ).send_event() ).send_event() else: status_message = "Service available" if serviceapidescription.get( "supportedFeatures") is None else "Service unavailable" current_app.logger.info(status_message) RedisEvent( "SERVICE_API_UNAVAILABLE", api_ids=[str(service_api_id)] ).send_event() return res return res except Exception as e: except Exception as e: Loading @@ -268,9 +240,18 @@ class PublishServiceOperations(Resource): "Updating service api with id: " + service_api_id) "Updating service api with id: " + service_api_id) my_query = {'apf_id': apf_id, 'api_id': service_api_id} my_query = {'apf_id': apf_id, 'api_id': service_api_id} serviceapidescription = mycol.find_one(my_query) serviceapidescription_old = mycol.find_one(my_query, {"_id": 0, "api_name": 1, if serviceapidescription is None: "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}) if serviceapidescription_old is None: current_app.logger.error(service_api_not_found_message) current_app.logger.error(service_api_not_found_message) return not_found_error(detail="Service API not existing", cause="Service API id not found") return not_found_error(detail="Service API not existing", cause="Service API id not found") Loading @@ -278,7 +259,7 @@ class PublishServiceOperations(Resource): service_api_description = clean_empty(service_api_description) service_api_description = clean_empty(service_api_description) result = mycol.find_one_and_update( result = mycol.find_one_and_update( serviceapidescription, serviceapidescription_old, {"$set": service_api_description}, {"$set": service_api_description}, projection={"_id": 0, projection={"_id": 0, "api_name": 1, "api_name": 1, Loading Loading @@ -307,39 +288,12 @@ class PublishServiceOperations(Resource): if response.status_code == 200: if response.status_code == 200: RedisEvent("SERVICE_API_UPDATE", RedisEvent("SERVICE_API_UPDATE", service_api_descriptions=[service_api_description_updated]).send_event() service_api_descriptions=[service_api_description_updated]).send_event() if service_api_description.api_status is None or len(service_api_description.api_status.aef_ids) > 0: if service_api_description.supported_features is not None: my_service_api = clean_n_camel_case(serviceapidescription_old) if service_api_description.return_supp_feat_dict(service_api_description.supported_features)["ApiStatusMonitoring"]: self.send_events_on_update( current_app.logger.info(f"Service available") service_api_id, RedisEvent("SERVICE_API_AVAILABLE", my_service_api, service_api_descriptions=[ service_api_description_updated) service_api_description], api_ids=[str(service_api_id)] ).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_AVAILABLE", api_ids=[str(service_api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_AVAILABLE", api_ids=[str(service_api_id)]).send_event() else: if service_api_description.supported_features is not None: if service_api_description.return_supp_feat_dict(service_api_description.supported_features)["ApiStatusMonitoring"]: current_app.logger.info(f"Service unavailable") RedisEvent("SERVICE_API_UNAVAILABLE", service_api_descriptions=[ service_api_description], api_ids=[str(service_api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_UNAVAILABLE", api_ids=[str(service_api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_UNAVAILABLE", api_ids=[str(service_api_id)]).send_event() return response return response Loading @@ -347,3 +301,46 @@ class PublishServiceOperations(Resource): exception = "An exception occurred in update service" exception = "An exception occurred in update service" current_app.logger.error(exception + "::" + str(e)) current_app.logger.error(exception + "::" + str(e)) return internal_server_error(detail=exception, cause=str(e)) return internal_server_error(detail=exception, cause=str(e)) def send_events_on_update(self, service_api_id, service_api_description_old, service_api_description_new): current_app.logger.debug("send Events if needed") service_api_status_event_old = self.service_api_availability_event( service_api_description_old) service_api_status_event_new = self.service_api_availability_event( service_api_description_old) if service_api_status_event_old == service_api_status_event_new: current_app.logger.info( "service_api_status not changed, it remains " + service_api_status_event_new + " Then no event will be sent") else: current_app.logger.info("service_api_status changed, event " + service_api_status_event_new + " Event will be sent") RedisEvent(service_api_status_event_new, service_api_descriptions=[ service_api_description_new], api_ids=[str(service_api_id)]).send_event() def service_api_availability_event(self, service_api_description): service_api_status = "" if ServiceAPIDescription.return_supp_feat_dict(service_api_description.get("supportedFeatures"))["ApiStatusMonitoring"]: current_app.logger.info( "ApiStatusMonitoring active") if service_api_description.get("apiStatus") is None or len(service_api_description.get("apiStatus").get("aefIds")) > 0: current_app.logger.info( "Service available, at least one AEF is available") service_api_status = "SERVICE_API_AVAILABLE" else: current_app.logger.info( "Service unavailable, all AEFs are unavailable") service_api_status = "SERVICE_API_UNAVAILABLE" else: current_app.logger.info("ApiStatusMonitoring") current_app.logger.info("Service available") service_api_status = "SERVICE_API_AVAILABLE" return service_api_status tests/resources/common/httpServerCtrl.robot→tests/features/Api Status/__init__.robot +2 −0 Original line number Original line Diff line number Diff line *** Settings *** *** Settings *** Force Tags api_status Library String No newline at end of file tests/features/Api Status/api_status.robot 0 → 100644 +320 −0 Original line number Original line Diff line number Diff line *** Settings *** Resource /opt/robot-tests/tests/resources/common.resource Library /opt/robot-tests/tests/libraries/bodyRequests.py Library XML Library String Resource /opt/robot-tests/tests/resources/common/basicRequests.robot Resource ../../resources/common.resource Suite Teardown Reset Testing Environment Test Setup Reset Testing Environment Test Teardown Reset Testing Environment *** Variables *** ${API_INVOKER_NOT_REGISTERED} not-valid ${SUBSCRIBER_ID_NOT_VALID} not-valid ${SUBSCRIPTION_ID_NOT_VALID} not-valid *** Test Cases *** Publish without apiStatus feature receive eventDetails with serviceAPIDescription [Tags] api_status-1 mockserver smoke # Initialize Mock server Init Mock Server # Default Invoker Registration and Onboarding ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # Register APF ${register_user_info_provider}= Provider Default Registration total_aef_roles=2 ${aef_id_1}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}']['aef_id']} ${aef_id_2}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}_1']['aef_id']} ${aef_ids}= Create List ${aef_id_1} ${aef_id_2} # Subscribe to events ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE ${request_body}= Create Events Subscription ... events=@{events_list} ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing ... supported_features=C ${resp}= Post Request Capif ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions ... json=${request_body} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} # Check Results Check Response Variable Type And Values ${resp} 201 EventSubscription ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # Publish api with 2 aefIds ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api ... ${register_user_info_provider} ... service_1 ... aef_id=${aef_ids} # Discover APIs by invoker ${resp}= Get Request Capif ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${aef_id_1} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs # Check Results Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} # Provider Remove service_1 published API ${resp}= Delete Request Capif ... ${resource_url.path} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${APF_PROVIDER_USERNAME} Status Should Be 204 ${resp} # Check Event Notifications ## Create check Events to ensure all notifications were received ${service_api_available_resources}= Create List ${resource_url} ${service_api_unavailable_resources}= Create List ${resource_url} ${events_expected}= Create Expected Events For Service API Notifications ... subscription_id=${subscription_id} ... service_api_available_resources=${service_api_available_resources} ... service_api_unavailable_resources=${service_api_unavailable_resources} ... event_detail_expected=${TRUE} ... service_api_description_expected=${TRUE} ... service_api_description=${service_api_description_published} ## Check Events Expected towards received notifications at mock server Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} Publish without apiStatus feature receive eventDetails without serviceAPIDescription [Tags] api_status-2 mockserver # Initialize Mock server Init Mock Server # Default Invoker Registration and Onboarding ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # Register APF ${register_user_info_provider}= Provider Default Registration total_aef_roles=2 ${aef_id_1}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}']['aef_id']} ${aef_id_2}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}_1']['aef_id']} ${aef_ids}= Create List ${aef_id_1} ${aef_id_2} # Subscribe to events ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE ${request_body}= Create Events Subscription ... events=@{events_list} ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing ... supported_features=4 ${resp}= Post Request Capif ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions ... json=${request_body} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} # Check Results Check Response Variable Type And Values ${resp} 201 EventSubscription ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # Publish api with 2 aefIds ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api ... ${register_user_info_provider} ... service_1 ... aef_id=${aef_ids} # Discover APIs by invoker ${resp}= Get Request Capif ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${aef_id_1} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs # Check Results Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} # Provider Remove service_1 published API ${resp}= Delete Request Capif ... ${resource_url.path} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${APF_PROVIDER_USERNAME} Status Should Be 204 ${resp} # Check Event Notifications ## Create check Events to ensure all notifications were received ${service_api_available_resources}= Create List ${resource_url} ${service_api_unavailable_resources}= Create List ${resource_url} ${events_expected}= Create Expected Events For Service API Notifications ... subscription_id=${subscription_id} ... service_api_available_resources=${service_api_available_resources} ... service_api_unavailable_resources=${service_api_unavailable_resources} ... event_detail_expected=${TRUE} ... service_api_description_expected=${FALSE} ... service_api_description=${service_api_description_published} ## Check Events Expected towards received notifications at mock server Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} #### ----- Publish without apiStatus feature receive eventDetails without eventDetails (apiMonitoringStatus active) [Tags] api_status-3 mockserver # Initialize Mock server Init Mock Server # Default Invoker Registration and Onboarding ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # Register APF ${register_user_info_provider}= Provider Default Registration total_aef_roles=2 ${aef_id_1}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}']['aef_id']} ${aef_id_2}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}_1']['aef_id']} ${aef_ids}= Create List ${aef_id_1} ${aef_id_2} # Subscribe to events ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE ${request_body}= Create Events Subscription ... events=@{events_list} ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing ... supported_features=8 ${resp}= Post Request Capif ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions ... json=${request_body} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} # Check Results Check Response Variable Type And Values ${resp} 201 EventSubscription ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # Publish api with 2 aefIds ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api ... ${register_user_info_provider} ... service_1 ... aef_id=${aef_ids} # Discover APIs by invoker ${resp}= Get Request Capif ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${aef_id_1} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs # Check Results Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} # Provider Remove service_1 published API ${resp}= Delete Request Capif ... ${resource_url.path} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${APF_PROVIDER_USERNAME} Status Should Be 204 ${resp} # Check Event Notifications ## Create check Events to ensure all notifications were received ${service_api_available_resources}= Create List ${resource_url} ${service_api_unavailable_resources}= Create List ${resource_url} ${events_expected}= Create Expected Events For Service API Notifications ... subscription_id=${subscription_id} ... service_api_available_resources=${service_api_available_resources} ... service_api_unavailable_resources=${service_api_unavailable_resources} ... event_detail_expected=${FALSE} ... service_api_description_expected=${FALSE} ... service_api_description=${service_api_description_published} ## Check Events Expected towards received notifications at mock server Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} ###--- # Invoker receives Service API Invocation events # [Tags] api_status-x mockserver smoke # # Initialize Mock server # Init Mock Server # # Default Invoker Registration and Onboarding # ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # # Register APF # ${register_user_info_provider}= Provider Default Registration # ${aef_id}= Set Variable ${register_user_info_provider['aef_id']} # # Subscribe to events # ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE # ${aef_ids}= Create List ${register_user_info_provider['aef_id']} # ${event_filter}= Create Capif Event Filter aefIds=${aef_ids} # ${event_filters}= Create List ${event_filter} # ${request_body}= Create Events Subscription # ... events=@{events_list} # ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing # ... event_filters=${event_filters} # ... supported_features=4 # ${resp}= Post Request Capif # ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions # ... json=${request_body} # ... server=${CAPIF_HTTPS_URL} # ... verify=ca.crt # ... username=${INVOKER_USERNAME} # # Check Results # Check Response Variable Type And Values ${resp} 201 EventSubscription # ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # # Publish one api # ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api # ... ${register_user_info_provider} # ... service_1 # # Provider Remove service_1 published API # ${resp}= Delete Request Capif # ... ${resource_url.path} # ... server=${CAPIF_HTTPS_URL} # ... verify=ca.crt # ... username=${APF_PROVIDER_USERNAME} # Status Should Be 204 ${resp} # # Check Event Notifications # ## Create check Events to ensure all notifications were received # ${service_api_available_resources}= Create List ${resource_url} # ${service_api_unavailable_resources}= Create List ${resource_url} # ${events_expected}= Create Expected Events For Service API Notifications # ... subscription_id=${subscription_id} # ... service_api_available_resources=${service_api_available_resources} # ... service_api_unavailable_resources=${service_api_unavailable_resources} # ## Check Events Expected towards received notifications at mock server # Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} tests/features/CAPIF Api Events/capif_events_api.robot +570 −160 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py +7 −0 Original line number Original line Diff line number Diff line Loading @@ -173,6 +173,13 @@ def apf_id_service_apis_service_api_id_put(service_api_id, apf_id, body): # noq current_app.logger.info( current_app.logger.info( "Updating service api id with id: " + service_api_id) "Updating service api id with id: " + service_api_id) 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"}] ) if request.is_json: if request.is_json: body = ServiceAPIDescription.from_dict(request.get_json()) # noqa: E501 body = ServiceAPIDescription.from_dict(request.get_json()) # noqa: E501 Loading
services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py +75 −78 Original line number Original line Diff line number Diff line Loading @@ -132,28 +132,13 @@ class PublishServiceOperations(Resource): if res.status_code == 201: if res.status_code == 201: current_app.logger.info("Service published") current_app.logger.info("Service published") if serviceapidescription.api_status is None or len(serviceapidescription.api_status.aef_ids) > 0: event_to_send = self.service_api_availability_event( if serviceapidescription.return_supp_feat_dict(serviceapidescription.supported_features)["ApiStatusMonitoring"]: clean_n_camel_case( current_app.logger.info(f"Service available") serviceapidescription_dict)) RedisEvent("SERVICE_API_AVAILABLE", RedisEvent(event_to_send, service_api_descriptions=[clean_n_camel_case( service_api_descriptions=[clean_n_camel_case( serviceapidescription.to_dict())], serviceapidescription.to_dict())], api_ids=[str(api_id)]).send_event() api_ids=[str(api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_AVAILABLE", api_ids=[str(api_id)]).send_event() else: if serviceapidescription.return_supp_feat_dict(serviceapidescription.supported_features)["ApiStatusMonitoring"]: current_app.logger.info(f"Service unavailable") RedisEvent("SERVICE_API_UNAVAILABLE", service_api_descriptions=[clean_n_camel_case( serviceapidescription.to_dict())], api_ids=[str(api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_UNAVAILABLE", api_ids=[str(api_id)]).send_event() return res return res Loading Loading @@ -229,11 +214,6 @@ class PublishServiceOperations(Resource): serviceapidescription = clean_empty( serviceapidescription = clean_empty( dict_to_camel_case(serviceapidescription_dict)) dict_to_camel_case(serviceapidescription_dict)) if res.status_code == 204: if res.status_code == 204: is_supported = serviceapidescription.get("supportedFeatures") and \ ServiceAPIDescription.return_supp_feat_dict( serviceapidescription["supportedFeatures"]).get("ApiStatusMonitoring") if is_supported: current_app.logger.info("Service unavailable") current_app.logger.info("Service unavailable") RedisEvent( RedisEvent( "SERVICE_API_UNAVAILABLE", "SERVICE_API_UNAVAILABLE", Loading @@ -241,14 +221,6 @@ class PublishServiceOperations(Resource): api_ids=[str(service_api_id)] api_ids=[str(service_api_id)] ).send_event() ).send_event() else: status_message = "Service available" if serviceapidescription.get( "supportedFeatures") is None else "Service unavailable" current_app.logger.info(status_message) RedisEvent( "SERVICE_API_UNAVAILABLE", api_ids=[str(service_api_id)] ).send_event() return res return res except Exception as e: except Exception as e: Loading @@ -268,9 +240,18 @@ class PublishServiceOperations(Resource): "Updating service api with id: " + service_api_id) "Updating service api with id: " + service_api_id) my_query = {'apf_id': apf_id, 'api_id': service_api_id} my_query = {'apf_id': apf_id, 'api_id': service_api_id} serviceapidescription = mycol.find_one(my_query) serviceapidescription_old = mycol.find_one(my_query, {"_id": 0, "api_name": 1, if serviceapidescription is None: "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}) if serviceapidescription_old is None: current_app.logger.error(service_api_not_found_message) current_app.logger.error(service_api_not_found_message) return not_found_error(detail="Service API not existing", cause="Service API id not found") return not_found_error(detail="Service API not existing", cause="Service API id not found") Loading @@ -278,7 +259,7 @@ class PublishServiceOperations(Resource): service_api_description = clean_empty(service_api_description) service_api_description = clean_empty(service_api_description) result = mycol.find_one_and_update( result = mycol.find_one_and_update( serviceapidescription, serviceapidescription_old, {"$set": service_api_description}, {"$set": service_api_description}, projection={"_id": 0, projection={"_id": 0, "api_name": 1, "api_name": 1, Loading Loading @@ -307,39 +288,12 @@ class PublishServiceOperations(Resource): if response.status_code == 200: if response.status_code == 200: RedisEvent("SERVICE_API_UPDATE", RedisEvent("SERVICE_API_UPDATE", service_api_descriptions=[service_api_description_updated]).send_event() service_api_descriptions=[service_api_description_updated]).send_event() if service_api_description.api_status is None or len(service_api_description.api_status.aef_ids) > 0: if service_api_description.supported_features is not None: my_service_api = clean_n_camel_case(serviceapidescription_old) if service_api_description.return_supp_feat_dict(service_api_description.supported_features)["ApiStatusMonitoring"]: self.send_events_on_update( current_app.logger.info(f"Service available") service_api_id, RedisEvent("SERVICE_API_AVAILABLE", my_service_api, service_api_descriptions=[ service_api_description_updated) service_api_description], api_ids=[str(service_api_id)] ).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_AVAILABLE", api_ids=[str(service_api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_AVAILABLE", api_ids=[str(service_api_id)]).send_event() else: if service_api_description.supported_features is not None: if service_api_description.return_supp_feat_dict(service_api_description.supported_features)["ApiStatusMonitoring"]: current_app.logger.info(f"Service unavailable") RedisEvent("SERVICE_API_UNAVAILABLE", service_api_descriptions=[ service_api_description], api_ids=[str(service_api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_UNAVAILABLE", api_ids=[str(service_api_id)]).send_event() else: current_app.logger.info("Service available") RedisEvent("SERVICE_API_UNAVAILABLE", api_ids=[str(service_api_id)]).send_event() return response return response Loading @@ -347,3 +301,46 @@ class PublishServiceOperations(Resource): exception = "An exception occurred in update service" exception = "An exception occurred in update service" current_app.logger.error(exception + "::" + str(e)) current_app.logger.error(exception + "::" + str(e)) return internal_server_error(detail=exception, cause=str(e)) return internal_server_error(detail=exception, cause=str(e)) def send_events_on_update(self, service_api_id, service_api_description_old, service_api_description_new): current_app.logger.debug("send Events if needed") service_api_status_event_old = self.service_api_availability_event( service_api_description_old) service_api_status_event_new = self.service_api_availability_event( service_api_description_old) if service_api_status_event_old == service_api_status_event_new: current_app.logger.info( "service_api_status not changed, it remains " + service_api_status_event_new + " Then no event will be sent") else: current_app.logger.info("service_api_status changed, event " + service_api_status_event_new + " Event will be sent") RedisEvent(service_api_status_event_new, service_api_descriptions=[ service_api_description_new], api_ids=[str(service_api_id)]).send_event() def service_api_availability_event(self, service_api_description): service_api_status = "" if ServiceAPIDescription.return_supp_feat_dict(service_api_description.get("supportedFeatures"))["ApiStatusMonitoring"]: current_app.logger.info( "ApiStatusMonitoring active") if service_api_description.get("apiStatus") is None or len(service_api_description.get("apiStatus").get("aefIds")) > 0: current_app.logger.info( "Service available, at least one AEF is available") service_api_status = "SERVICE_API_AVAILABLE" else: current_app.logger.info( "Service unavailable, all AEFs are unavailable") service_api_status = "SERVICE_API_UNAVAILABLE" else: current_app.logger.info("ApiStatusMonitoring") current_app.logger.info("Service available") service_api_status = "SERVICE_API_AVAILABLE" return service_api_status
tests/resources/common/httpServerCtrl.robot→tests/features/Api Status/__init__.robot +2 −0 Original line number Original line Diff line number Diff line *** Settings *** *** Settings *** Force Tags api_status Library String No newline at end of file
tests/features/Api Status/api_status.robot 0 → 100644 +320 −0 Original line number Original line Diff line number Diff line *** Settings *** Resource /opt/robot-tests/tests/resources/common.resource Library /opt/robot-tests/tests/libraries/bodyRequests.py Library XML Library String Resource /opt/robot-tests/tests/resources/common/basicRequests.robot Resource ../../resources/common.resource Suite Teardown Reset Testing Environment Test Setup Reset Testing Environment Test Teardown Reset Testing Environment *** Variables *** ${API_INVOKER_NOT_REGISTERED} not-valid ${SUBSCRIBER_ID_NOT_VALID} not-valid ${SUBSCRIPTION_ID_NOT_VALID} not-valid *** Test Cases *** Publish without apiStatus feature receive eventDetails with serviceAPIDescription [Tags] api_status-1 mockserver smoke # Initialize Mock server Init Mock Server # Default Invoker Registration and Onboarding ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # Register APF ${register_user_info_provider}= Provider Default Registration total_aef_roles=2 ${aef_id_1}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}']['aef_id']} ${aef_id_2}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}_1']['aef_id']} ${aef_ids}= Create List ${aef_id_1} ${aef_id_2} # Subscribe to events ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE ${request_body}= Create Events Subscription ... events=@{events_list} ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing ... supported_features=C ${resp}= Post Request Capif ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions ... json=${request_body} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} # Check Results Check Response Variable Type And Values ${resp} 201 EventSubscription ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # Publish api with 2 aefIds ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api ... ${register_user_info_provider} ... service_1 ... aef_id=${aef_ids} # Discover APIs by invoker ${resp}= Get Request Capif ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${aef_id_1} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs # Check Results Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} # Provider Remove service_1 published API ${resp}= Delete Request Capif ... ${resource_url.path} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${APF_PROVIDER_USERNAME} Status Should Be 204 ${resp} # Check Event Notifications ## Create check Events to ensure all notifications were received ${service_api_available_resources}= Create List ${resource_url} ${service_api_unavailable_resources}= Create List ${resource_url} ${events_expected}= Create Expected Events For Service API Notifications ... subscription_id=${subscription_id} ... service_api_available_resources=${service_api_available_resources} ... service_api_unavailable_resources=${service_api_unavailable_resources} ... event_detail_expected=${TRUE} ... service_api_description_expected=${TRUE} ... service_api_description=${service_api_description_published} ## Check Events Expected towards received notifications at mock server Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} Publish without apiStatus feature receive eventDetails without serviceAPIDescription [Tags] api_status-2 mockserver # Initialize Mock server Init Mock Server # Default Invoker Registration and Onboarding ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # Register APF ${register_user_info_provider}= Provider Default Registration total_aef_roles=2 ${aef_id_1}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}']['aef_id']} ${aef_id_2}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}_1']['aef_id']} ${aef_ids}= Create List ${aef_id_1} ${aef_id_2} # Subscribe to events ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE ${request_body}= Create Events Subscription ... events=@{events_list} ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing ... supported_features=4 ${resp}= Post Request Capif ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions ... json=${request_body} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} # Check Results Check Response Variable Type And Values ${resp} 201 EventSubscription ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # Publish api with 2 aefIds ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api ... ${register_user_info_provider} ... service_1 ... aef_id=${aef_ids} # Discover APIs by invoker ${resp}= Get Request Capif ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${aef_id_1} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs # Check Results Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} # Provider Remove service_1 published API ${resp}= Delete Request Capif ... ${resource_url.path} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${APF_PROVIDER_USERNAME} Status Should Be 204 ${resp} # Check Event Notifications ## Create check Events to ensure all notifications were received ${service_api_available_resources}= Create List ${resource_url} ${service_api_unavailable_resources}= Create List ${resource_url} ${events_expected}= Create Expected Events For Service API Notifications ... subscription_id=${subscription_id} ... service_api_available_resources=${service_api_available_resources} ... service_api_unavailable_resources=${service_api_unavailable_resources} ... event_detail_expected=${TRUE} ... service_api_description_expected=${FALSE} ... service_api_description=${service_api_description_published} ## Check Events Expected towards received notifications at mock server Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} #### ----- Publish without apiStatus feature receive eventDetails without eventDetails (apiMonitoringStatus active) [Tags] api_status-3 mockserver # Initialize Mock server Init Mock Server # Default Invoker Registration and Onboarding ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # Register APF ${register_user_info_provider}= Provider Default Registration total_aef_roles=2 ${aef_id_1}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}']['aef_id']} ${aef_id_2}= Set Variable ${register_user_info_provider['aef_roles']['${AEF_PROVIDER_USERNAME}_1']['aef_id']} ${aef_ids}= Create List ${aef_id_1} ${aef_id_2} # Subscribe to events ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE ${request_body}= Create Events Subscription ... events=@{events_list} ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing ... supported_features=8 ${resp}= Post Request Capif ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions ... json=${request_body} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} # Check Results Check Response Variable Type And Values ${resp} 201 EventSubscription ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # Publish api with 2 aefIds ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api ... ${register_user_info_provider} ... service_1 ... aef_id=${aef_ids} # Discover APIs by invoker ${resp}= Get Request Capif ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${aef_id_1} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${INVOKER_USERNAME} Check Response Variable Type And Values ${resp} 200 DiscoveredAPIs # Check Results Dictionary Should Contain Key ${resp.json()} serviceAPIDescriptions Should Not Be Empty ${resp.json()['serviceAPIDescriptions']} Length Should Be ${resp.json()['serviceAPIDescriptions']} 1 List Should Contain Value ${resp.json()['serviceAPIDescriptions']} ${service_api_description_published} # Provider Remove service_1 published API ${resp}= Delete Request Capif ... ${resource_url.path} ... server=${CAPIF_HTTPS_URL} ... verify=ca.crt ... username=${APF_PROVIDER_USERNAME} Status Should Be 204 ${resp} # Check Event Notifications ## Create check Events to ensure all notifications were received ${service_api_available_resources}= Create List ${resource_url} ${service_api_unavailable_resources}= Create List ${resource_url} ${events_expected}= Create Expected Events For Service API Notifications ... subscription_id=${subscription_id} ... service_api_available_resources=${service_api_available_resources} ... service_api_unavailable_resources=${service_api_unavailable_resources} ... event_detail_expected=${FALSE} ... service_api_description_expected=${FALSE} ... service_api_description=${service_api_description_published} ## Check Events Expected towards received notifications at mock server Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected} ###--- # Invoker receives Service API Invocation events # [Tags] api_status-x mockserver smoke # # Initialize Mock server # Init Mock Server # # Default Invoker Registration and Onboarding # ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding # # Register APF # ${register_user_info_provider}= Provider Default Registration # ${aef_id}= Set Variable ${register_user_info_provider['aef_id']} # # Subscribe to events # ${events_list}= Create List SERVICE_API_AVAILABLE SERVICE_API_UNAVAILABLE # ${aef_ids}= Create List ${register_user_info_provider['aef_id']} # ${event_filter}= Create Capif Event Filter aefIds=${aef_ids} # ${event_filters}= Create List ${event_filter} # ${request_body}= Create Events Subscription # ... events=@{events_list} # ... notification_destination=${NOTIFICATION_DESTINATION_URL}/testing # ... event_filters=${event_filters} # ... supported_features=4 # ${resp}= Post Request Capif # ... /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions # ... json=${request_body} # ... server=${CAPIF_HTTPS_URL} # ... verify=ca.crt # ... username=${INVOKER_USERNAME} # # Check Results # Check Response Variable Type And Values ${resp} 201 EventSubscription # ${subscriber_id} ${subscription_id}= Check Event Location Header ${resp} # # Publish one api # ${service_api_description_published} ${resource_url} ${request_body}= Publish Service Api # ... ${register_user_info_provider} # ... service_1 # # Provider Remove service_1 published API # ${resp}= Delete Request Capif # ... ${resource_url.path} # ... server=${CAPIF_HTTPS_URL} # ... verify=ca.crt # ... username=${APF_PROVIDER_USERNAME} # Status Should Be 204 ${resp} # # Check Event Notifications # ## Create check Events to ensure all notifications were received # ${service_api_available_resources}= Create List ${resource_url} # ${service_api_unavailable_resources}= Create List ${resource_url} # ${events_expected}= Create Expected Events For Service API Notifications # ... subscription_id=${subscription_id} # ... service_api_available_resources=${service_api_available_resources} # ... service_api_unavailable_resources=${service_api_unavailable_resources} # ## Check Events Expected towards received notifications at mock server # Wait Until Keyword Succeeds 5x 5s Check Mock Server Notification Events ${events_expected}
tests/features/CAPIF Api Events/capif_events_api.robot +570 −160 File changed.Preview size limit exceeded, changes collapsed. Show changes