diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py index 5a11c591ab4f2004c411e06723a2ac639d111f59..00cf9b7d902663a8ef93e804fd5379e967af66a2 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py @@ -103,7 +103,8 @@ class LoggingInvocationOperations(Resource): current_app.logger.info(event) invocation_log_base['logs']=[log] - RedisEvent(event,invocation_log_base,"invocationLogs").send_event() + invocationLogs=[invocation_log_base] + RedisEvent(event,"invocationLogs",invocationLogs).send_event() current_app.logger.debug("After log check") diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py index d42a1efdfa179bcba3aa4be13a7afc29bd5cdbdb..037eade61b29ba5c9caa526527a4c69c056dfbb6 100644 --- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py +++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py @@ -4,19 +4,37 @@ import json publisher_ops = Publisher() + class RedisEvent(): - def __init__(self, event, information, event_detail_key) -> None: - self.redis_event={ + def __init__(self, event, event_detail_key, information) -> None: + self.EVENTS_ENUM = [ + 'SERVICE_API_AVAILABLE', + 'SERVICE_API_UNAVAILABLE', + 'SERVICE_API_UPDATE', + 'API_INVOKER_ONBOARDED', + 'API_INVOKER_OFFBOARDED', + 'SERVICE_API_INVOCATION_SUCCESS', + 'SERVICE_API_INVOCATION_FAILURE', + 'ACCESS_CONTROL_POLICY_UPDATE', + 'ACCESS_CONTROL_POLICY_UNAVAILABLE', + 'API_INVOKER_AUTHORIZATION_REVOKED', + 'API_INVOKER_UPDATED', + 'API_TOPOLOGY_HIDING_CREATED', + 'API_TOPOLOGY_HIDING_REVOKED'] + if event not in self.EVENTS_ENUM: + raise Exception( + "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")") + self.redis_event = { "event": event, "key": event_detail_key, - "information":information + "information": information } - + def to_string(self): return json.dumps(self.redis_event, cls=JSONEncoder) - + def send_event(self): - publisher_ops.publish_message("events-log",self.to_string()) - + publisher_ops.publish_message("events-log", self.to_string()) + def __call__(self): - return self.redis_event \ No newline at end of file + return self.redis_event diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py index 8fc2b6269ac2c0363ca96b3d3e76cdac7edeba01..66368031eb92e0a332dfe755cdb6826a23bc1cb0 100644 --- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py @@ -15,6 +15,7 @@ from cryptography.hazmat.backends import default_backend from ..core.validate_user import ControlAccess from functools import wraps import pymongo +from ..core.redis_event import RedisEvent service_operations = PublishServiceOperations() @@ -84,7 +85,8 @@ def apf_id_service_apis_post(apf_id, body): # noqa: E501 if res.status_code == 201: current_app.logger.info("Service published") - publisher_ops.publish_message("events", "SERVICE_API_AVAILABLE") + api_id=res.headers['Location'].split('/')[-1] + RedisEvent("SERVICE_API_AVAILABLE", "apiIds", [api_id] ).send_event() return res @@ -107,7 +109,7 @@ def apf_id_service_apis_service_api_id_delete(service_api_id, apf_id): # noqa: if res.status_code == 204: current_app.logger.info("Removed service published") - publisher_ops.publish_message("events", "SERVICE_API_UNAVAILABLE") + RedisEvent("SERVICE_API_UNAVAILABLE", "apiIds", [service_api_id] ).send_event() publisher_ops.publish_message("internal-messages", f"service-removed:{service_api_id}") return res diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/redis_event.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/redis_event.py new file mode 100644 index 0000000000000000000000000000000000000000..037eade61b29ba5c9caa526527a4c69c056dfbb6 --- /dev/null +++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/redis_event.py @@ -0,0 +1,40 @@ +from ..encoder import JSONEncoder +from .publisher import Publisher +import json + +publisher_ops = Publisher() + + +class RedisEvent(): + def __init__(self, event, event_detail_key, information) -> None: + self.EVENTS_ENUM = [ + 'SERVICE_API_AVAILABLE', + 'SERVICE_API_UNAVAILABLE', + 'SERVICE_API_UPDATE', + 'API_INVOKER_ONBOARDED', + 'API_INVOKER_OFFBOARDED', + 'SERVICE_API_INVOCATION_SUCCESS', + 'SERVICE_API_INVOCATION_FAILURE', + 'ACCESS_CONTROL_POLICY_UPDATE', + 'ACCESS_CONTROL_POLICY_UNAVAILABLE', + 'API_INVOKER_AUTHORIZATION_REVOKED', + 'API_INVOKER_UPDATED', + 'API_TOPOLOGY_HIDING_CREATED', + 'API_TOPOLOGY_HIDING_REVOKED'] + if event not in self.EVENTS_ENUM: + raise Exception( + "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")") + self.redis_event = { + "event": event, + "key": event_detail_key, + "information": information + } + + def to_string(self): + return json.dumps(self.redis_event, cls=JSONEncoder) + + def send_event(self): + publisher_ops.publish_message("events-log", self.to_string()) + + def __call__(self): + return self.redis_event diff --git a/services/run_capif_tests.sh b/services/run_capif_tests.sh index 4da86224ea2182893a0dc05a64f17be9105912fa..90be28d2a73f59af9892c9d843d08c6d0ae02498 100755 --- a/services/run_capif_tests.sh +++ b/services/run_capif_tests.sh @@ -25,7 +25,7 @@ CAPIF_VAULT_PORT=8200 # CAPIF_VAULT_TOKEN=dev-only-token CAPIF_VAULT_TOKEN=read-ca-token -MOCK_SERVER_URL=http://192.168.0.14:9090 +MOCK_SERVER_URL=http://10.95.115.22:9090 echo "CAPIF_HOSTNAME = $CAPIF_HOSTNAME" diff --git a/tests/features/CAPIF Api Events/capif_events_api.robot b/tests/features/CAPIF Api Events/capif_events_api.robot index afb44dabd5047a6df6944bb00b3a9639da8cbbd0..0e9ebf8ec3bcb215ab9b5d61727cc82a6b02322f 100644 --- a/tests/features/CAPIF Api Events/capif_events_api.robot +++ b/tests/features/CAPIF Api Events/capif_events_api.robot @@ -2,6 +2,7 @@ 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 @@ -138,119 +139,8 @@ Deletes an individual CAPIF Event Subscription with invalid SubscriptionId ... detail=User not authorized ... cause=You are not the owner of this resource -# Prueba Mock Server -# [Tags] jms-3 -# Start Mock server - -# Prueba JMS -# [Tags] jms-1 - -# # Start Mock server -# Check Mock Server -# Clean Mock Server - -# # Register APF -# ${register_user_info}= Provider Default Registration - -# # Publish one api -# Publish Service Api ${register_user_info} - -# # Register INVOKER -# ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding - -# ${discover_response}= Get Request Capif -# ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']} -# ... server=${CAPIF_HTTPS_URL} -# ... verify=ca.crt -# ... username=${INVOKER_USERNAME} - -# ${api_ids} ${api_names}= Get Api Ids And Names From Discover Response ${discover_response} - -# # Subscribe to events -# ${events_list}= Create List SERVICE_API_INVOCATION_SUCCESS SERVICE_API_INVOCATION_FAILURE -# ${request_body}= Create Events Subscription -# ... events=@{events_list} -# ... notificationDestination=http://192.168.0.14:9090/testing -# ${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} - -# ${results}= Create List 200 400 - -# # Create Log Entry -# ${request_body}= Create Log Entry -# ... ${register_user_info['aef_id']} -# ... ${register_user_info_invoker['api_invoker_id']} -# ... ${api_ids} -# ... ${api_names} -# ... results=${results} -# ${resp}= Post Request Capif -# ... /api-invocation-logs/v1/${register_user_info['aef_id']}/logs -# ... json=${request_body} -# ... server=${CAPIF_HTTPS_URL} -# ... verify=ca.crt -# ... username=${AEF_PROVIDER_USERNAME} - -# # Check Results -# Check Response Variable Type And Values ${resp} 201 InvocationLog -# ${resource_url}= Check Location Header ${resp} ${LOCATION_LOGGING_RESOURCE_REGEX} - -# Sleep 3s - -# # Get from Mock server the EventNotification Messages sent to callback setup on event subscription. -# ${resp}= Get Mock Server Messages -# ${notification_events_on_mock_server}= Set Variable ${resp.json()} -# # Check if message follow EventNotification definition. -# Check Variable ${notification_events_on_mock_server} EventNotification -# # Check if mock server receive 2 events. -# Length Should Be ${notification_events_on_mock_server} 2 - -# # Now we create the expected events received at notification server according to logs sent to loggin service in order to check if all are present. -# ${invocation_log_base}= Copy Dictionary ${request_body} deepcopy=True - -# # Store log array because each log will be notified in one Event Notification -# ${invocation_log_logs}= Set Variable ${invocation_log_base['logs']} -# # Remove logs array from invocationLog data -# Remove From Dictionary ${invocation_log_base} logs -# Length Should Be ${invocation_log_logs} 2 - -# # Create 2 invocationLogs from initial invocationLog present on request -# ${invocation_logs_1}= Copy Dictionary ${invocation_log_base} deepcopy=True -# ${invocation_logs_2}= Copy Dictionary ${invocation_log_base} deepcopy=True -# # Create a log array with only one component -# ${log_1}= Create List ${invocation_log_logs[0]} -# ${log_2}= Create List ${invocation_log_logs[1]} -# # Setup logs array with previously created list -# Set To Dictionary ${invocation_logs_1} logs=${log_1} -# Set To Dictionary ${invocation_logs_2} logs=${log_2} -# # Create event details for each log -# ${event_details_1}= Create dictionary invocationLogs=${invocation_logs_1} -# ${event_details_2}= Create dictionary invocationLogs=${invocation_logs_2} -# # Create Event with Event Details from invocationLog -# ${event_1}= Create Dictionary -# ... subscriptionId=${subscription_id} -# ... events=SERVICE_API_INVOCATION_SUCCESS -# ... eventDetail=${event_details_1} -# ${event_2}= Create Dictionary -# ... subscriptionId=${subscription_id} -# ... events=SERVICE_API_INVOCATION_FAILURE -# ... eventDetail=${event_details_2} -# # Check if created events follow EventNotification format defined by 3gpp -# Check Variable ${event_1} EventNotification -# Check Variable ${event_2} EventNotification - -# List Should Contain Value ${notification_events_on_mock_server} ${event_1} -# List Should Contain Value ${notification_events_on_mock_server} ${event_2} - Invoker receives Service API Invocation events - [Tags] capif_api_events-6 mockserver + [Tags] capif_api_events-6 mockserver # Start Mock server Check Mock Server @@ -275,9 +165,9 @@ Invoker receives Service API Invocation events # Subscribe to events ${events_list}= Create List SERVICE_API_INVOCATION_SUCCESS SERVICE_API_INVOCATION_FAILURE - ${aef_ids}= Create List ${register_user_info['aef_id']} - ${event_filter}= Create Capif Event Filter aefIds=${aef_ids} - ${event_filters}= Create List ${event_filter} + ${aef_ids}= Create List ${register_user_info['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} @@ -322,7 +212,7 @@ Invoker receives Service API Invocation events Check Variable ${notification_events_on_mock_server} EventNotification # Create check Events to ensure all notifications were received - ${check_events} ${check_events_length}= Create Events From invocationLogs + ${check_events} ${check_events_length}= Create Events From InvocationLogs ... ${subscription_id} ... ${request_body} @@ -333,3 +223,91 @@ Invoker receives Service API Invocation events Log ${event} List Should Contain Value ${notification_events_on_mock_server} ${event} END + +Invoker subscribe to Service API Available and Unavailable events + [Tags] capif_api_events-7 mockserver + + # Start Mock server + Check Mock Server + Clean Mock Server + + # Register APF + ${register_user_info_provider}= Provider Default Registration + + # Publish one api + ${service_api_description_published_1} ${resource_url_1} ${request_body}= Publish Service Api + ... ${register_user_info_provider} + + # Register INVOKER + ${register_user_info_invoker} ${url} ${request_body}= Invoker Default Onboarding + + ${discover_response}= Get Request Capif + ... ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${INVOKER_USERNAME} + + ${api_ids} ${api_names}= Get Api Ids And Names From Discover Response ${discover_response} + + # 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} + ... notificationDestination=${MOCK_SERVER_URL}/testing + ... eventFilters=${event_filters} + ${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} + + # Provider publish new API + ${service_api_description_published_2} ${resource_url_2} ${request_body}= Publish Service Api + ... ${register_user_info_provider} + ... service_2 + + # Provider Remove service_1 published API + ${resp}= Delete Request Capif + ... ${resource_url_1.path} + ... server=${CAPIF_HTTPS_URL} + ... verify=ca.crt + ... username=${APF_PROVIDER_USERNAME} + + Status Should Be 204 ${resp} + + # Check Results + + Sleep 3s + # Get from Mock server the EventNotification Messages sent to callback setup on event subscription. + ${resp}= Get Mock Server Messages + ${notification_events_on_mock_server}= Set Variable ${resp.json()} + # Check if message follow EventNotification definition. + Check Variable ${notification_events_on_mock_server} EventNotification + + # Create Notification Events expected to be received + ${api_id_1}= Fetch From Right ${resource_url_1.path} / + ${notification_event_expected_removed}= Create Notification Event + ... ${subscription_id} + ... SERVICE_API_UNAVAILABLE + ... apiIds=${api_id_1} + Check Variable ${notification_event_expected_removed} EventNotification + ${api_id_2}= Fetch From Right ${resource_url_2.path} / + ${notification_event_expected_created}= Create Notification Event + ... ${subscription_id} + ... SERVICE_API_AVAILABLE + ... apiIds=${api_id_2} + Check Variable ${notification_event_expected_created} EventNotification + + # Check results + Length Should Be ${notification_events_on_mock_server} 2 + List Should Contain Value ${notification_events_on_mock_server} ${notification_event_expected_removed} + List Should Contain Value ${notification_events_on_mock_server} ${notification_event_expected_created} diff --git a/tests/libraries/api_events/bodyRequests.py b/tests/libraries/api_events/bodyRequests.py index 3d1de2663e313908da543430e4a569e5c40c5cf7..24f22f3dfc21b11b923ddc795bd071358dd2fb30 100644 --- a/tests/libraries/api_events/bodyRequests.py +++ b/tests/libraries/api_events/bodyRequests.py @@ -45,3 +45,51 @@ def create_websock_notif_config_default(): "websocketUri": "websocketUri" } +def create_notification_event(subscriptionId, event, serviceAPIDescriptions=None, apiIds=None, apiInvokerIds=None, accCtrlPolList=None, invocationLogs=None, apiTopoHide=None): + result={ + "subscriptionId":subscriptionId, + "events": event, + "eventDetail": dict() + } + count=0 + if serviceAPIDescriptions != None: + if isinstance(serviceAPIDescriptions,list()): + result['eventDetail']['serviceAPIDescriptions']=serviceAPIDescriptions + else: + result['eventDetail']['serviceAPIDescriptions']=[serviceAPIDescriptions] + count=count+1 + if apiIds != None: + if isinstance(apiIds,list): + result['eventDetail']['apiIds']=apiIds + else: + result['eventDetail']['apiIds']=[apiIds] + count=count+1 + if apiInvokerIds != None: + if isinstance(apiInvokerIds,list): + result['eventDetail']['apiInvokerIds']=apiInvokerIds + else: + result['eventDetail']['apiInvokerIds']=[apiInvokerIds] + count=count+1 + if accCtrlPolList != None: + if isinstance(accCtrlPolList,list): + result['eventDetail']['accCtrlPolList']=accCtrlPolList + else: + result['eventDetail']['accCtrlPolList']=[accCtrlPolList] + count=count+1 + if invocationLogs != None: + if isinstance(invocationLogs,list): + result['eventDetail']['invocationLogs']=invocationLogs + else: + result['eventDetail']['invocationLogs']=[invocationLogs] + count=count+1 + if apiTopoHide != None: + if isinstance(apiTopoHide): + result['eventDetail']['apiTopoHide']=apiTopoHide + else: + result['eventDetail']['apiTopoHide']=[apiTopoHide] + count=count+1 + + if count == 0: + del result['eventDetail'] + + return result diff --git a/tests/resources/common/basicRequests.robot b/tests/resources/common/basicRequests.robot index 9565fb01e331e16cb8e3b098f8949d84d47dac43..9ba5f21538253c838cf5ca6f57162b7cabef150b 100644 --- a/tests/resources/common/basicRequests.robot +++ b/tests/resources/common/basicRequests.robot @@ -747,7 +747,7 @@ Create Security Context Between invoker and provider Check Response Variable Type And Values ${resp} 201 ServiceSecurity -Create Events From invocationLogs +Create Events From InvocationLogs [Arguments] ${subscription_id} ${invocation_log} ${events}= Create List @@ -774,13 +774,7 @@ Create Events From invocationLogs ${log_list}= Create List ${log} # Setup logs array with previously created list Set To Dictionary ${invocation_logs} logs=${log_list} - # Create event details for each log - ${event_details}= Create dictionary invocationLogs=${invocation_logs} - # Create Event with Event Details from invocationLog and also is appended to events array - ${event}= Create Dictionary - ... subscriptionId=${subscription_id} - ... events=${event_enum} - ... eventDetail=${event_details} + ${event}= Create Notification Event ${subscription_id} ${event_enum} invocationLogs=${invocation_logs} Check Variable ${event} EventNotification Append To List ${events} ${event} END