add comments
[vfc/nfvo/lcm.git] / lcm / ns / views / sol / subscriptions_view.py
1 # Copyright (c) 2019, CMCC Technologies Co., Ltd.
2
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6
7 # http://www.apache.org/licenses/LICENSE-2.0
8
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import ast
16 import json
17 import logging
18
19 from drf_yasg.utils import swagger_auto_schema
20 from lcm.ns.serializers.sol.lccn_subscription import LccnSubscriptionSerializer
21 from lcm.ns.serializers.sol.lccn_subscription import LccnSubscriptionsSerializer
22 from rest_framework import status
23 from rest_framework.response import Response
24 from rest_framework.views import APIView
25
26 from lcm.ns.biz.create_subscription import CreateSubscription
27 from lcm.ns.biz.query_subscription import QuerySubscription
28 from lcm.ns.serializers.sol.lccn_subscription_request import LccnSubscriptionRequestSerializer
29 from lcm.ns.serializers.sol.pub_serializers import ProblemDetailsSerializer
30 from lcm.pub.exceptions import NSLCMException
31 from lcm.pub.exceptions import BadRequestException
32 from .common import view_safe_call_with_log
33
34 logger = logging.getLogger(__name__)
35 VALID_FILTERS = [
36     "operationTypes",
37     "operationStates",
38     "notificationTypes",
39     "nsInstanceId",
40     "nsComponentTypes",
41     "lcmOpNameImpactingNsComponent",
42     "lcmOpOccStatusImpactingNsComponent"
43 ]
44
45
46 def get_problem_details_serializer(status_code, error_message):
47     problem_details = {
48         "status": status_code,
49         "detail": error_message
50     }
51     problem_details_serializer = ProblemDetailsSerializer(data=problem_details)
52     problem_details_serializer.is_valid()
53     return problem_details_serializer
54
55
56 class SubscriptionsView(APIView):
57     """
58     This resource represents subscriptions.
59     The client can use this resource to subscribe to notifications related to NS lifecycle management, and to query its subscriptions.
60     """
61     @swagger_auto_schema(
62         request_body=LccnSubscriptionRequestSerializer(),
63         responses={
64             status.HTTP_201_CREATED: LccnSubscriptionSerializer(),
65             status.HTTP_303_SEE_OTHER: ProblemDetailsSerializer(),
66             status.HTTP_500_INTERNAL_SERVER_ERROR: ProblemDetailsSerializer()
67         }
68     )
69     @view_safe_call_with_log(logger=logger)
70     def post(self, request):
71         """
72         The POST method creates a new subscription.
73         :param request:
74         :return:
75         """
76         logger.debug("SubscribeNotification--post::> %s" % request.data)
77
78         lccn_subscription_request_serializer = LccnSubscriptionRequestSerializer(
79             data=request.data)
80         if not lccn_subscription_request_serializer.is_valid():
81             raise BadRequestException(
82                 lccn_subscription_request_serializer.errors)
83         subscription = CreateSubscription(
84             lccn_subscription_request_serializer.data).do_biz()
85         lccn_notifications_filter = {
86             "notificationTypes": ast.literal_eval(subscription.notification_types),
87             "operationTypes": ast.literal_eval(subscription.operation_types),
88             "operationStates": ast.literal_eval(subscription.operation_states),
89             "nsInstanceSubscriptionFilter": json.loads(subscription.ns_instance_filter),
90             "nsComponentTypes": ast.literal_eval(subscription.ns_component_types),
91             "lcmOpNameImpactingNsComponent": ast.literal_eval(subscription.
92                                                               lcm_opname_impacting_nscomponent),
93             "lcmOpOccStatusImpactingNsComponent": ast.literal_eval(subscription.
94                                                                    lcm_opoccstatus_impacting_nscomponent)
95         }
96         subscription_data = {
97             "id": subscription.subscription_id,
98             "callbackUri": subscription.callback_uri,
99             "_links": json.loads(subscription.links),
100             "filter": lccn_notifications_filter
101         }
102         sub_resp_serializer = LccnSubscriptionSerializer(
103             data=subscription_data)
104         if not sub_resp_serializer.is_valid():
105             raise NSLCMException(sub_resp_serializer.errors)
106         return Response(data=subscription_data, status=status.HTTP_201_CREATED)
107
108     @swagger_auto_schema(
109         responses={
110             status.HTTP_200_OK: LccnSubscriptionsSerializer(),
111             status.HTTP_400_BAD_REQUEST: ProblemDetailsSerializer(),
112             status.HTTP_500_INTERNAL_SERVER_ERROR: ProblemDetailsSerializer()
113         }
114     )
115     @view_safe_call_with_log(logger=logger)
116     def get(self, request):
117         """
118         The GET method queries the list of active subscriptions of the functional block that invokes the method.
119         It can be used e.g. for resynchronization after error situations.
120         :param request:
121         :return:
122         """
123         logger.debug("SubscribeNotification--get::> %s" % request.query_params)
124
125         if request.query_params and not set(request.query_params).issubset(set(VALID_FILTERS)):
126             problem_details_serializer = get_problem_details_serializer(
127                 status.HTTP_400_BAD_REQUEST, "Not a valid filter")
128             return Response(data=problem_details_serializer.data, status=status.HTTP_400_BAD_REQUEST)
129         resp_data = QuerySubscription(request.query_params).query_multi_subscriptions()
130         subscriptions_serializer = LccnSubscriptionsSerializer(data=resp_data)
131         if not subscriptions_serializer.is_valid():
132             raise NSLCMException(subscriptions_serializer.errors)
133         logger.debug("SubscribeNotification--get::> Remove default fields if exclude_default is "
134                      "specified")
135         return Response(data=resp_data, status=status.HTTP_200_OK)