Commit 9dda8838 authored by Stavros-Anastasios Charismiadis's avatar Stavros-Anastasios Charismiadis
Browse files

Merge branch 'OCF129-events-api-supported-feature-negotiation' into 'staging'

Add feature negotiation on Events API, change supported feature attribute in...

See merge request !119
parents eefae489 2f2d04f0
Loading
Loading
Loading
Loading
Loading
+55 −18
Original line number Original line Diff line number Diff line
@@ -11,6 +11,21 @@ from .responses import internal_server_error, not_found_error, make_response, ba
from ..util import serialize_clean_camel_case, clean_empty, dict_to_camel_case
from ..util import serialize_clean_camel_case, clean_empty, dict_to_camel_case




TOTAL_FEATURES = 4
SUPPORTED_FEATURES_HEX = "c"

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]

    return {
        "NotificationTestEvent": True if final_supp_feat[0] == "1" else False,
        "NotificationWebsocket": True if final_supp_feat[1] == "1" else False,
        "EnhancedEventReport": True if final_supp_feat[2] == "1" else False,
        "ApiStatusMonitoring": True if final_supp_feat[3] == "1" else False,
        "Final": hex(int(final_supp_feat[::-1], 2))[2:]
    }

class EventSubscriptionsOperations(Resource):
class EventSubscriptionsOperations(Resource):


    def __check_subscriber_id(self, subscriber_id):
    def __check_subscriber_id(self, subscriber_id):
@@ -87,9 +102,10 @@ class EventSubscriptionsOperations(Resource):


                return result
                return result


            # Check if EnhancedEventReport is enabled and validate event filters
            negotiated_supported_features = return_negotiated_supp_feat_dict(event_subscription.supported_features)


            if EventSubscription.return_supp_feat_dict(event_subscription.supported_features)["EnhancedEventReport"]:
            # Check if EnhancedEventReport is enabled and validate event filters
            if negotiated_supported_features["EnhancedEventReport"]:
                if event_subscription.event_filters:
                if event_subscription.event_filters:
                    current_app.logger.debug(event_subscription.event_filters)
                    current_app.logger.debug(event_subscription.event_filters)
                    result = self.__check_event_filters(event_subscription.events, clean_empty(event_subscription.to_dict()["event_filters"]))
                    result = self.__check_event_filters(event_subscription.events, clean_empty(event_subscription.to_dict()["event_filters"]))
@@ -109,6 +125,10 @@ class EventSubscriptionsOperations(Resource):
            evnt = dict()
            evnt = dict()
            evnt["subscriber_id"] = subscriber_id
            evnt["subscriber_id"] = subscriber_id
            evnt["subscription_id"] = subscription_id
            evnt["subscription_id"] = subscription_id

            # Edit supported_features field to the negotiated one
            event_subscription.supported_features = negotiated_supported_features["Final"]

            evnt.update(event_subscription.to_dict())
            evnt.update(event_subscription.to_dict())
            mycol.insert_one(evnt)
            mycol.insert_one(evnt)


@@ -178,18 +198,31 @@ class EventSubscriptionsOperations(Resource):
            if  isinstance(result, Response):
            if  isinstance(result, Response):
                return result
                return result


            if EventSubscription.return_supp_feat_dict(event_subscription.supported_features)["EnhancedEventReport"] and event_subscription.event_filters:
                result = self.__check_event_filters(event_subscription.events, clean_empty(event_subscription.to_dict()["event_filters"]))
                if  isinstance(result, Response):
                    return result

            my_query = {'subscriber_id': subscriber_id,
            my_query = {'subscriber_id': subscriber_id,
                        'subscription_id': subscription_id}
                        'subscription_id': subscription_id}
            eventdescription = mycol.find_one(my_query)
            eventdescription = mycol.find_one(my_query)


            if eventdescription is None:
            if eventdescription is None:
                current_app.logger.error("Event subscription not found")
                current_app.logger.error("Event subscription not found")
                return not_found_error(detail="Event subscription not exist", cause="Event API subscription id not found")
                return not_found_error(detail="Event subscription not exist",
                                       cause="Event API subscription id not found")

            negotiated_supported_features = return_negotiated_supp_feat_dict(event_subscription.supported_features)

            if negotiated_supported_features["EnhancedEventReport"] and event_subscription.event_filters:
                result = self.__check_event_filters(event_subscription.events, clean_empty(event_subscription.to_dict()["event_filters"]))
                if  isinstance(result, Response):
                    return result
            elif (not negotiated_supported_features["EnhancedEventReport"]) and event_subscription.event_filters:
                current_app.logger.error("Event filters provided but EnhancedEventReport is not enabled")
                return bad_request_error(
                    detail="Bad Param",
                    cause="Event filters provided but EnhancedEventReport is not enabled",
                    invalid_params=[{"param": "eventFilters", "reason": "EnhancedEventReport is not enabled"}]
                )

            event_subscription.supported_features = negotiated_supported_features["Final"]

            body = event_subscription.to_dict()
            body = event_subscription.to_dict()


            body["subscriber_id"] = subscriber_id
            body["subscriber_id"] = subscriber_id
@@ -228,7 +261,9 @@ class EventSubscriptionsOperations(Resource):
                current_app.logger.error("Event subscription not found")
                current_app.logger.error("Event subscription not found")
                return not_found_error(detail="Event subscription not exist", cause="Event API subscription id not found")
                return not_found_error(detail="Event subscription not exist", cause="Event API subscription id not found")


            if EventSubscription.return_supp_feat_dict(eventdescription.get("supported_features"))["EnhancedEventReport"]:
            negotiated_supported_features = return_negotiated_supp_feat_dict(eventdescription.get("supported_features"))

            if negotiated_supported_features["EnhancedEventReport"]:
                if event_subscription.events and event_subscription.event_filters:
                if event_subscription.events and event_subscription.event_filters:
                    result = self.__check_event_filters(event_subscription.events, clean_empty(event_subscription.to_dict()["event_filters"]))
                    result = self.__check_event_filters(event_subscription.events, clean_empty(event_subscription.to_dict()["event_filters"]))
                elif event_subscription.events and  event_subscription.event_filters is None and eventdescription.get("event_filters", None):
                elif event_subscription.events and  event_subscription.event_filters is None and eventdescription.get("event_filters", None):
@@ -239,6 +274,8 @@ class EventSubscriptionsOperations(Resource):
                if  isinstance(result, Response):
                if  isinstance(result, Response):
                    return result
                    return result


            event_subscription.supported_features = negotiated_supported_features["Final"]

            body = clean_empty(event_subscription.to_dict())
            body = clean_empty(event_subscription.to_dict())
            document = mycol.update_one(my_query, {"$set":body})
            document = mycol.update_one(my_query, {"$set":body})
            document = mycol.find_one(my_query)
            document = mycol.find_one(my_query)
+17 −3
Original line number Original line Diff line number Diff line
@@ -13,6 +13,20 @@ from util import serialize_clean_camel_case


from .internal_event_ops import InternalEventOperations
from .internal_event_ops import InternalEventOperations


TOTAL_FEATURES = 4
SUPPORTED_FEATURES_HEX = "c"

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]

    return {
        "NotificationTestEvent": True if final_supp_feat[0] == "1" else False,
        "NotificationWebsocket": True if final_supp_feat[1] == "1" else False,
        "EnhancedEventReport": True if final_supp_feat[2] == "1" else False,
        "ApiStatusMonitoring": True if final_supp_feat[3] == "1" else False,
        "Final": hex(int(final_supp_feat[::-1], 2))[2:]
    }


class Notifications():
class Notifications():


@@ -36,7 +50,7 @@ class Notifications():
                data = EventNotification(sub["subscription_id"], events=event)
                data = EventNotification(sub["subscription_id"], events=event)
                event_detail_redis=redis_event.get('event_detail', None)
                event_detail_redis=redis_event.get('event_detail', None)
                if event_detail_redis is not None:
                if event_detail_redis is not None:
                    if EventSubscription.return_supp_feat_dict(sub["supported_features"])["EnhancedEventReport"]:
                    if return_negotiated_supp_feat_dict(sub["supported_features"])["EnhancedEventReport"]:
                        event_detail={}
                        event_detail={}
                        current_app.logger.debug(f"event: {event_detail_redis}")
                        current_app.logger.debug(f"event: {event_detail_redis}")


@@ -54,13 +68,13 @@ class Notifications():
                                api_ids_list = event_filter.get("api_ids", None)
                                api_ids_list = event_filter.get("api_ids", None)
                                if api_ids_list and event_detail_redis.get('apiIds', None)[0] in api_ids_list:
                                if api_ids_list and event_detail_redis.get('apiIds', None)[0] in api_ids_list:
                                    event_detail["apiIds"]=event_detail_redis.get('apiIds', None)
                                    event_detail["apiIds"]=event_detail_redis.get('apiIds', None)
                                    if EventSubscription.return_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"]:
                                    if return_negotiated_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"]:
                                        event_detail["serviceAPIDescriptions"]=event_detail_redis.get('serviceAPIDescriptions', None)
                                        event_detail["serviceAPIDescriptions"]=event_detail_redis.get('serviceAPIDescriptions', None)
                                else:
                                else:
                                    continue
                                    continue
                            else:
                            else:
                                event_detail["apiIds"]=event_detail_redis.get('apiIds', None)
                                event_detail["apiIds"]=event_detail_redis.get('apiIds', None)
                                if EventSubscription.return_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"]:
                                if return_negotiated_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"]:
                                    event_detail["serviceAPIDescriptions"]=event_detail_redis.get('serviceAPIDescriptions', None)
                                    event_detail["serviceAPIDescriptions"]=event_detail_redis.get('serviceAPIDescriptions', None)
                        elif event in ["SERVICE_API_UPDATE"]:
                        elif event in ["SERVICE_API_UPDATE"]:
                            if event_filter:
                            if event_filter:
+0 −12
Original line number Original line Diff line number Diff line
@@ -62,18 +62,6 @@ class EventSubscription(Model):
        self._websock_notif_config = websock_notif_config
        self._websock_notif_config = websock_notif_config
        self._supported_features = supported_features
        self._supported_features = supported_features


    @classmethod
    def return_supp_feat_dict(cls, supp_feat):
        TOTAL_FEATURES=4
        supp_feat_in_hex = int(supp_feat, 16)
        supp_feat_in_bin = bin(supp_feat_in_hex)[2:].zfill(TOTAL_FEATURES)[::-1]

        return {
            "NotificationTestEvent": True if supp_feat_in_bin[0] == "1" else False,
            "NotificationWebsocket": True if supp_feat_in_bin[1] == "1" else False,
            "EnhancedEventReport": True if supp_feat_in_bin[2] == "1" else False,
            "ApiStatusMonitoring": True if supp_feat_in_bin[3] == "1" else False
        }
    
    
    @classmethod
    @classmethod
    def from_dict(cls, dikt) -> 'EventSubscription':
    def from_dict(cls, dikt) -> 'EventSubscription':