[PMSH] Delete subscription API by Name
[dcaegen2/services.git] / components / pm-subscription-handler / pmsh_service / mod / api / controller.py
1 # ============LICENSE_START===================================================
2 #  Copyright (C) 2019-2022 Nordix Foundation.
3 # ============================================================================
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #      http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16 # SPDX-License-Identifier: Apache-2.0
17 # ============LICENSE_END=====================================================
18
19 from http import HTTPStatus
20 from mod import logger
21 from mod.api.services import subscription_service, measurement_group_service
22 from connexion import NoContent
23 from mod.api.custom_exception import InvalidDataException, DuplicateDataException
24
25
26 def status():
27     """
28     Returns the health of the PMSH service
29     Args:
30         NA
31     Returns:
32         Dictionary detailing 'status' of either 'healthy' or 'unhealthy'.
33     Raises:
34         NA
35     """
36     return {'status': 'healthy'}
37
38
39 def post_subscription(body):
40     """
41     Creates a subscription
42
43     Args:
44         body (dict): subscription request body to save.
45
46     Returns:
47         Success : NoContent, 201
48         Invalid Data : Invalid message, 400
49         Duplicate Data : Duplicate field detail, 409
50
51     Raises:
52         Error: If anything fails in the server.
53     """
54     response = NoContent, HTTPStatus.CREATED.value
55     try:
56         subscription_service.create_subscription(body['subscription'])
57     except DuplicateDataException as e:
58         logger.error(f'Failed to create subscription for '
59                      f'{body["subscription"]["subscriptionName"]} due to duplicate data: {e}',
60                      exc_info=True)
61         response = e.duplicate_field_info, HTTPStatus.CONFLICT.value
62     except InvalidDataException as e:
63         logger.error(f'Failed to create subscription for '
64                      f'{body["subscription"]["subscriptionName"]} due to invalid data: {e}',
65                      exc_info=True)
66         response = e.invalid_message, HTTPStatus.BAD_REQUEST.value
67     return response
68
69
70 def get_subscription_by_name(subscription_name):
71     """
72     Retrieves subscription based on the name
73
74     Args:
75         subscription_name (String): Name of the subscription.
76
77     Returns:
78        dict, HTTPStatus: single Sub in PMSH, 200
79        dict, HTTPStatus: subscription not defined, 404
80        dict, HTTPStatus: Exception details of failure, 500
81     """
82     logger.info('API call received to fetch subscription by name')
83     try:
84         subscription = subscription_service.query_subscription_by_name(subscription_name)
85         if subscription is not None:
86             logger.info(f'queried subscription was successful with the name: {subscription_name}')
87             return subscription.serialize(), HTTPStatus.OK.value
88         else:
89             logger.error('queried subscription was un successful with the name: '
90                          f'{subscription_name}')
91             return {'error': 'Subscription was not defined with the name : '
92                              f'{subscription_name}'}, HTTPStatus.NOT_FOUND.value
93     except Exception as exception:
94         logger.error(f'While querying the subscription with name: {subscription_name}, '
95                      f'it occurred the following exception "{exception}"')
96         return {'error': 'Request was not processed due to Exception : '
97                          f'{exception}'}, HTTPStatus.INTERNAL_SERVER_ERROR.value
98
99
100 def get_subscriptions():
101     """ Retrieves all the subscriptions that are defined in PMSH.
102
103     Returns:
104        list (dict), HTTPStatus: All subs in PMSH, 200
105        dict, HTTPStatus: Exception details of failure, 500
106     """
107     logger.info('API call received to fetch all subscriptions')
108     try:
109         subscriptions = subscription_service.get_subscriptions_list()
110         return subscriptions, HTTPStatus.OK.value
111     except Exception as exception:
112         logger.error(f'The following exception occurred while fetching subscriptions: {exception}')
113         return {'error': 'Request was not processed due to Exception : '
114                          f'{exception}'}, HTTPStatus.INTERNAL_SERVER_ERROR.value
115
116
117 def get_meas_group_with_nfs(subscription_name, measurement_group_name):
118     """
119     Retrieves the measurement group and it's associated network functions
120
121     Args:
122         subscription_name (String): Name of the subscription.
123         measurement_group_name (String): Name of the measurement group
124
125     Returns:
126        dict, HTTPStatus: measurement group info with associated nfs, 200
127        dict, HTTPStatus: measurement group was not defined, 404
128        dict, HTTPStatus: Exception details of failure, 500
129     """
130     logger.info('API call received to query measurement group and associated network'
131                 f' functions by using sub name: {subscription_name} and measurement '
132                 f'group name: {measurement_group_name}')
133     try:
134         meas_group = measurement_group_service.query_meas_group_by_name(subscription_name,
135                                                                         measurement_group_name)
136         if meas_group is not None:
137             return meas_group.meas_group_with_nfs(), HTTPStatus.OK.value
138         else:
139             logger.error('measurement group was not defined with the sub name: '
140                          f'{subscription_name} and meas group name: '
141                          f'{measurement_group_name}')
142             return {'error': 'measurement group was not defined with the sub name: '
143                              f'{subscription_name} and meas group name: '
144                              f'{measurement_group_name}'}, HTTPStatus.NOT_FOUND.value
145     except Exception as exception:
146         logger.error('The following exception occurred while fetching measurement group: '
147                      f'{exception}')
148         return {'error': 'Request was not processed due to Exception : '
149                          f'{exception}'}, HTTPStatus.INTERNAL_SERVER_ERROR.value
150
151
152 def delete_subscription_by_name(subscription_name):
153     """ Deletes the subscription by name
154
155     Args:
156         subscription_name (String): Name of the subscription
157
158     Returns:
159        NoneType, HTTPStatus: None, 204
160        dict, HTTPStatus: subscription not defined, 404
161        dict, HTTPStatus: Reason for not deleting subscription, 409
162        dict, HTTPStatus: Exception details of failure, 500
163     """
164     logger.info(f'API call received to delete subscription by name: {subscription_name}')
165     try:
166         unlocked_locking_mgs = \
167             subscription_service.query_unlocked_mg_by_sub_name(subscription_name)
168         if not unlocked_locking_mgs:
169             if subscription_service.query_to_delete_subscription_by_name(subscription_name) == 1:
170                 return None, HTTPStatus.NO_CONTENT
171             else:
172                 logger.error(f'Subscription is not defined with name {subscription_name}')
173                 return {'error': f'Subscription is not defined with name {subscription_name}'}, \
174                     HTTPStatus.NOT_FOUND.value
175         else:
176             logger.error('Subscription is not deleted due to associated MGs were UNLOCKED '
177                          '(or) under update process to LOCKED')
178             return {'error': 'Subscription is not deleted due to the following MGs were UNLOCKED '
179                     '(or) under update process to LOCKED', 'measurementGroupNames':
180                         [{'measurementGroupName':
181                             mg.measurement_group_name}for mg in unlocked_locking_mgs]}, \
182                 HTTPStatus.CONFLICT.value
183     except Exception as exception:
184         logger.error(f'Try again, subscription with name {subscription_name}'
185                      f'is not deleted due to following exception: {exception}')
186         return {'error': f'Try again, subscription with name {subscription_name}'
187                          f'is not deleted due to following exception: {exception}'}, \
188             HTTPStatus.INTERNAL_SERVER_ERROR.value