Commit 9ba4d4fd authored by Pelayo Torres's avatar Pelayo Torres
Browse files

Merge branch 'staging' into...

Merge branch 'staging' into OCF92-review-all-location-resource-header-created-according-to-events-service
parents d8b0c0ea e955e835
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -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


+75 −78
Original line number Original line Diff line number Diff line
@@ -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


@@ -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",
@@ -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:
@@ -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")


@@ -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,
@@ -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


@@ -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
+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
+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}
+570 −160

File changed.

Preview size limit exceeded, changes collapsed.

Loading