Commit 52815fee authored by Stavros-Anastasios Charismiadis's avatar Stavros-Anastasios Charismiadis
Browse files

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

Add feature negotiation on Events API, change supported feature attribute in API response to match the negotiated one
parent 1a835c3a
Loading
Loading
Loading
Loading
Loading
+48 −18
Original line number 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


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):

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

                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:
                    current_app.logger.debug(event_subscription.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["subscriber_id"] = subscriber_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())
            mycol.insert_one(evnt)

@@ -178,18 +198,24 @@ class EventSubscriptionsOperations(Resource):
            if  isinstance(result, Response):
                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,
                        'subscription_id': subscription_id}
            eventdescription = mycol.find_one(my_query)

            if eventdescription is None:
                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

            event_subscription.supported_features = negotiated_supported_features["Final"]

            body = event_subscription.to_dict()

            body["subscriber_id"] = subscriber_id
@@ -228,7 +254,9 @@ class EventSubscriptionsOperations(Resource):
                current_app.logger.error("Event subscription 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:
                    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):
@@ -239,6 +267,8 @@ class EventSubscriptionsOperations(Resource):
                if  isinstance(result, Response):
                    return result

            event_subscription.supported_features = negotiated_supported_features["Final"]

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

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():

@@ -36,7 +50,7 @@ class Notifications():
                data = EventNotification(sub["subscription_id"], events=event)
                event_detail_redis=redis_event.get('event_detail', 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={}
                        current_app.logger.debug(f"event: {event_detail_redis}")

@@ -54,13 +68,13 @@ class Notifications():
                                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:
                                    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)
                                else:
                                    continue
                            else:
                                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)
                        elif event in ["SERVICE_API_UPDATE"]:
                            if event_filter:
+0 −12
Original line number Diff line number Diff line
@@ -62,18 +62,6 @@ class EventSubscription(Model):
        self._websock_notif_config = websock_notif_config
        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
    def from_dict(cls, dikt) -> 'EventSubscription':