fix bug for failure in creating subscriptions for vnfm
[vfc/nfvo/driver/vnfm/gvnfm.git] / gvnfmadapter / driver / interfaces / views.py
1 # Copyright 2017 ZTE Corporation.
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 inspect
16 import json
17 import logging
18 import time
19 import traceback
20
21 from drf_yasg.utils import swagger_auto_schema
22 from rest_framework import status
23 from rest_framework.response import Response
24 from rest_framework.views import APIView
25
26 from driver.interfaces.serializers.serializers import VnfInstReqParamsSerializer, ResponseSerializer
27 from driver.interfaces.serializers.serializers import VnfNotifyReqSerializer, VNFLCMOpOccSerializer
28 from driver.interfaces.serializers.serializers import VnfOperRespSerializer
29 from driver.interfaces.serializers.serializers import VnfTermReqSerializer, VnfQueryRespSerializer
30 from driver.interfaces.serializers.grant_request import GrantRequestSerializer
31 from driver.interfaces.serializers.grant import GrantSerializer
32 from driver.interfaces.serializers.lccn_subscription import LccnSubscriptionSerializer
33 from driver.interfaces.serializers.lccn_subscription_request import LccnSubscriptionRequestSerializer
34 from driver.pub.exceptions import GvnfmDriverException
35 from driver.pub.utils import restcall
36 from driver.pub.utils.restcall import req_by_msb
37 from driver.interfaces.serializers.operate_request import VnfOperateRequestSerializer
38 from driver.interfaces.serializers.heal_request import HealVnfRequestSerializerToVnfm, VnfHealRequestSerializer
39 from driver.interfaces.serializers.response import ProblemDetailSerializer
40
41 logger = logging.getLogger(__name__)
42
43
44 class VnfInstInfo(APIView):
45     @swagger_auto_schema(
46         request_body=VnfInstReqParamsSerializer(),
47         responses={
48             status.HTTP_201_CREATED: ResponseSerializer(),
49             status.HTTP_404_NOT_FOUND: "The vnfm instance id is wrong",
50             status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
51         }
52     )
53     def post(self, request, vnfmtype, vnfmid):
54         logger.debug("instantiate_vnf--post::> %s" % request.data)
55         logger.debug("Create vnf begin!")
56         try:
57             requestSerializer = VnfInstReqParamsSerializer(data=request.data)
58             request_isValid = requestSerializer.is_valid()
59             if not request_isValid:
60                 raise Exception(requestSerializer.errors)
61
62             # requestData = requestSerializer.data
63             requestData = request.data
64             input_data = {
65                 "vnfdId": ignorcase_get(requestData, "vnfDescriptorId"),
66                 "vnfInstanceName": ignorcase_get(requestData, "vnfInstanceName"),
67                 "vnfInstanceDescription": ignorcase_get(requestData, "vnfInstanceDescription"),
68                 "vnfmInstId": vnfmid
69             }
70             vnfm_id = vnfmid
71             logger.debug("do_createvnf: request data=[%s],input_data=[%s],vnfm_id=[%s]",
72                          request.data, input_data, vnfm_id)
73             resp = do_createvnf(vnfm_id, input_data)
74             logger.debug("do_createvnf: response data=[%s]", resp)
75             logger.debug("Create vnf end!")
76
77             logger.debug("Instantiate vnf start!")
78             vnfInstanceId = resp["id"]
79             input_data = {
80                 "flavourId": ignorcase_get(requestData, "flavourId"),
81                 "extVirtualLinks": ignorcase_get(requestData, "extVirtualLink"),
82                 "additionalParams": ignorcase_get(requestData, "additionalParam"),
83             }
84             logger.debug("do_instvnf: vnfInstanceId=[%s],request data=[%s],input_data=[%s],vnfm_id=[%s]",
85                          vnfInstanceId, request.data, input_data, vnfm_id)
86             resp = do_instvnf(vnfInstanceId, vnfm_id, input_data)
87             logger.debug("do_instvnf: response data=[%s]", resp)
88             resp_data = {
89                 "vnfInstanceId": vnfInstanceId,
90                 "jobId": ignorcase_get(resp, "jobId")
91             }
92             logger.debug("Instantiate vnf end!")
93             return Response(data=resp_data, status=status.HTTP_201_CREATED)
94         except GvnfmDriverException as e:
95             logger.error('instantiate vnf failed, detail message: %s' % e.args[0])
96             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
97         except:
98             logger.error(traceback.format_exc())
99             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
100
101
102 class VnfTermInfo(APIView):
103     @swagger_auto_schema(
104         request_body=VnfTermReqSerializer(),
105         responses={
106             status.HTTP_201_CREATED: ResponseSerializer(),
107             status.HTTP_404_NOT_FOUND: "The vnfmid and vnfInstanceId are wrong",
108             status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
109         }
110     )
111     def post(self, request, vnfmtype, vnfmid, vnfInstanceId):
112         logger.debug("terminate_vnf--post::> %s" % request.data)
113         vnfm_id = vnfmid
114         try:
115             vnf_info = do_queryvnf(request, vnfm_id, vnfInstanceId)
116             logger.debug("VNF instance info: %s" % vnf_info)
117         except GvnfmDriverException as e:
118             logger.debug('VNF already does not exist, detail message: %s' % e.args[0])
119             return Response(data={"vnfInstanceId": vnfInstanceId}, status=status.HTTP_201_CREATED)
120
121         try:
122             if vnf_info.get("instantiationState", "") == "INSTANTIATED":
123                 term_type = ignorcase_get(request.data, "terminationType")
124                 input_data = {
125                     "terminationType": term_type.upper() if term_type else "FORCEFUL"
126                 }
127                 term_timeout = ignorcase_get(request.data, "gracefulTerminationTimeout")
128                 if term_timeout:
129                     input_data["gracefulTerminationTimeout"] = int(term_timeout)
130
131                 logger.debug("do_terminatevnf: vnfm_id=[%s],vnfInstanceId=[%s],input_data=[%s]",
132                              vnfm_id, vnfInstanceId, input_data)
133                 resp = do_terminatevnf(vnfm_id, vnfInstanceId, input_data)
134                 logger.debug("terminate_vnf: response data=[%s]", resp)
135                 jobId = ignorcase_get(resp, "jobId")
136                 logger.debug("wait4job: vnfm_id=[%s],jobId=[%s]", vnfm_id, jobId)
137                 resp = wait4job(vnfm_id, jobId)
138                 logger.debug("[wait4job] response=[%s]", resp)
139
140             resp = do_deletevnf(vnfm_id, vnfInstanceId)
141             logger.debug("do_deletevnf: response data=[%s]", resp)
142             resp_data = {
143                 "vnfInstanceId": vnfInstanceId
144             }
145             return Response(data=resp_data, status=status.HTTP_201_CREATED)
146         except GvnfmDriverException as e:
147             logger.error('Terminate vnf failed, detail message: %s' % e.args[0])
148             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
149         except:
150             logger.error(traceback.format_exc())
151             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
152
153
154 class VnfQueryInfo(APIView):
155     @swagger_auto_schema(
156         responses={
157             status.HTTP_201_CREATED: VnfQueryRespSerializer(),
158             status.HTTP_404_NOT_FOUND: "The vnfmid and vnfInstanceId are wrong",
159             status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
160         }
161     )
162     def get(self, request, vnfmtype, vnfmid, vnfInstanceId):
163         logger.debug("query_vnf--post::> %s" % request.data)
164         vnfm_id = vnfmid
165         try:
166             logger.debug("[%s] request.data=%s", fun_name(), request.data)
167             resp = do_queryvnf(request, vnfm_id, vnfInstanceId)
168             query_vnf_resp_mapping = {
169                 "vnfInstanceId": "",
170                 "vnfInstanceName": "",
171                 "vnfInstanceDescription": "",
172                 "vnfdId": "",
173                 "vnfPackageId": "",
174                 "version": "",
175                 "vnfProvider": "",
176                 "vnfType": "",
177                 "vnfStatus": ""
178             }
179             ResponseInfo = ignorcase_get(resp, "ResponseInfo")
180             resp_response_data = mapping_conv(query_vnf_resp_mapping, ResponseInfo)
181             resp_data = {
182                 "vnfInfo": resp_response_data
183             }
184             id = ignorcase_get(ResponseInfo, "id")
185             if id:
186                 resp_data["vnfInfo"]["vnfInstanceId"] = id
187             vnfPkgId = ignorcase_get(ResponseInfo, "vnfPkgId")
188             if vnfPkgId:
189                 resp_data["vnfInfo"]["vnfPackageId"] = vnfPkgId
190             vnfSoftwareVersion = ignorcase_get(ResponseInfo, "vnfSoftwareVersion")
191             if vnfSoftwareVersion:
192                 resp_data["vnfInfo"]["version"] = vnfSoftwareVersion
193             if ignorcase_get(ResponseInfo, "instantiationState") == "INSTANTIATED":
194                 resp_data["vnfInfo"]["vnfStatus"] = "ACTIVE"
195             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
196             return Response(data=resp_data, status=status.HTTP_200_OK)
197         except GvnfmDriverException as e:
198             logger.error('Query vnf failed, detail message: %s' % e.args[0])
199             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
200         except:
201             logger.error(traceback.format_exc())
202             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
203
204
205 class VnfOperInfo(APIView):
206     @swagger_auto_schema(
207         responses={
208             status.HTTP_201_CREATED: VnfOperRespSerializer(),
209             status.HTTP_404_NOT_FOUND: "The vnfmid, jobid and responseId are wrong",
210             status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
211         }
212     )
213     def get(self, request, vnfmtype, vnfmid, jobid):
214         logger.debug("operation_status--post::> %s" % request.data)
215         try:
216             logger.debug("[%s] request.data=%s", fun_name(), request.data)
217             vnfm_id = vnfmid
218             jobId = jobid
219             responseId = ignorcase_get(request.META, 'responseId')
220             logger.debug("[operation_status] vnfm_id=%s", vnfm_id)
221             vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
222             logger.debug("[operation_status] vnfm_info=[%s]", vnfm_info)
223
224             ret = call_vnfm("api/vnflcm/v1/vnf_lc_ops/%s?responseId=%s" % (jobId, responseId), "GET", vnfm_info)
225             if ret[0] != 0:
226                 logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
227                 raise GvnfmDriverException('Failed to query vnf operation status.')
228             resp_data = json.JSONDecoder().decode(ret[1])
229             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
230             # ResponseInfo = ignorcase_get(resp_data, "ResponseInfo")
231             responseDescriptor = ignorcase_get(resp_data, "responseDescriptor")
232             status_tmp = ignorcase_get(responseDescriptor, "status")
233             # del responseDescriptor["lcmOperationStatus"]
234             responseDescriptor["status"] = status_tmp
235             operation_data = {
236                 "jobId": ignorcase_get(resp_data, "jobId"),
237                 "responseDescriptor": responseDescriptor
238             }
239             return Response(data=operation_data, status=status.HTTP_200_OK)
240         except GvnfmDriverException as e:
241             logger.error('Query vnf failed, detail message: %s' % e.args[0])
242             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
243         except:
244             logger.error(traceback.format_exc())
245             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
246
247
248 class VnfGrantInfo(APIView):
249     @swagger_auto_schema(
250         request_body=GrantRequestSerializer(),  # TODO: not used
251         responses={
252             status.HTTP_201_CREATED: GrantSerializer(),
253             status.HTTP_404_NOT_FOUND: "The request body is wrong",
254             status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
255         }
256     )
257     def put(self, request, vnfmtype):
258         try:
259             logger.debug("[grantvnf] req_data = %s", request.data)
260             grant_request = GrantRequestSerializer(data=request.data)
261             if not grant_request.is_valid():
262                 raise GvnfmDriverException(grant_request.error_messages)
263             ret = req_by_msb('api/nslcm/v2/grants', "POST", content=json.JSONEncoder().encode(request.data))
264             logger.debug("ret = %s", ret)
265             if ret[0] != 0:
266                 logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
267                 raise GvnfmDriverException('Failed to grant vnf.')
268             resp = json.JSONDecoder().decode(ret[1])
269             grant = GrantSerializer(data=resp)
270             if not grant.is_valid():
271                 logger.warn(grant.error_messages)
272                 # raise GvnfmDriverException(grant.error_messages)
273             logger.debug("[%s]resp_data=%s", fun_name(), resp)
274             return Response(data=resp, status=status.HTTP_201_CREATED)
275         except GvnfmDriverException as e:
276             logger.error('Grant vnf failed, detail message: %s' % e.args[0])
277             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
278         except:
279             logger.error(traceback.format_exc())
280             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
281
282
283 class VnfNotifyInfo(APIView):
284     def get(self, request, vnfmtype):
285         try:
286             logger.debug("[%s]receive request.", fun_name())
287             return Response(status=status.HTTP_204_NO_CONTENT)
288         except:
289             logger.error(traceback.format_exc())
290             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
291
292     @swagger_auto_schema(
293         request_body=VnfNotifyReqSerializer(),
294         responses={
295             status.HTTP_201_CREATED: "Successful Notify",
296             status.HTTP_404_NOT_FOUND: "The request body is wrong",
297             status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
298         }
299     )
300     def post(self, request, vnfmtype):  # TODO: not compatable with VnfIdentifierCreationNotification and VnfIdentifierDeletionNotification
301         try:
302             logger.debug("[%s]req_data = %s", fun_name(), request.data)
303             vnfminstid = ignorcase_get(request.data, 'vnfmInstId')
304             vnfinstanceid = ignorcase_get(request.data, 'vnfInstanceId')
305             request.data.pop("vnfmInstId")
306             ret = req_by_msb("api/nslcm/v2/ns/%s/vnfs/%s/Notify" % (vnfminstid, vnfinstanceid), "POST",
307                              json.JSONEncoder().encode(request.data))
308             logger.debug("[%s]data = %s", fun_name(), ret)
309             if ret[0] != 0:
310                 logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
311                 raise GvnfmDriverException('Failed to notify vnf.')
312             return Response(data=None, status=status.HTTP_200_OK)
313         except GvnfmDriverException as e:
314             logger.error('Grant vnf failed, detail message: %s' % e.args[0])
315             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
316         except:
317             logger.error(traceback.format_exc())
318             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
319
320
321 class VnfOperateView(APIView):
322     @swagger_auto_schema(
323         request_body=VnfOperateRequestSerializer(),
324         responses={
325             status.HTTP_202_ACCEPTED: "Success",
326             status.HTTP_404_NOT_FOUND: ProblemDetailSerializer(),
327             status.HTTP_409_CONFLICT: ProblemDetailSerializer(),
328             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
329         }
330     )
331     def post(self, request, vnfmtype, vnfmid, vnfInstanceId):
332         logger.debug("operate_vnf--post::> %s" % request.data)
333         logger.debug("Operate vnf begin!")
334         try:
335             requestSerializer = VnfOperateRequestSerializer(data=request.data)
336             request_isValid = requestSerializer.is_valid()
337             if not request_isValid:
338                 raise Exception(requestSerializer.errors)
339             logger.debug("Operate vnf start!")
340             logger.debug("do_operate: vnfmid=[%s],vnfInstanceId=[%s],request data=[%s]",
341                          vnfmid, vnfInstanceId, request.data)
342             statusCode, resp, location = do_lcmVnf(vnfmid, vnfInstanceId, request.data, "operate")
343             logger.debug("do_operate: response data=[%s]", resp)
344             logger.debug("Operate vnf end!")
345             ret = int(statusCode)
346             if ret == status.HTTP_404_NOT_FOUND:
347                 return Response(data=resp, status=status.HTTP_404_NOT_FOUND)
348             elif ret == status.HTTP_409_CONFLICT:
349                 return Response(data=resp, status=status.HTTP_409_CONFLICT)
350             response = Response(data=resp, status=status.HTTP_202_ACCEPTED)
351             response["Location"] = location
352             return response
353         except GvnfmDriverException as e:
354             logger.error('operate vnf failed, detail message: %s' % e.args[0])
355             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
356         except:
357             logger.error(traceback.format_exc())
358             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
359
360
361 class VnfHealView(APIView):
362     @swagger_auto_schema(
363         request_body=VnfHealRequestSerializer(),
364         responses={
365             status.HTTP_202_ACCEPTED: "Success",
366             status.HTTP_404_NOT_FOUND: ProblemDetailSerializer(),
367             status.HTTP_409_CONFLICT: ProblemDetailSerializer(),
368             status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
369         }
370     )
371     def post(self, request, vnfmtype, vnfmid, vnfInstanceId):
372         logger.debug("Heal_vnf--post::> %s" % request.data)
373         logger.debug("Heal vnf begin!")
374         try:
375             requestSerializer = VnfHealRequestSerializer(data=request.data)
376             request_isValid = requestSerializer.is_valid()
377             if not request_isValid:
378                 raise Exception(requestSerializer.errors)
379             healdata = {
380                 u"additionalParams": {
381                     u"action": ignorcase_get(request.data, "action"),
382                     u"affectedvm": ignorcase_get(request.data, "affectedvm")
383                 }
384             }
385             input_data = HealVnfRequestSerializerToVnfm(data=healdata)
386             resp_isvalid = input_data.is_valid()
387             if not resp_isvalid:
388                 raise GvnfmDriverException(input_data.errors)
389             logger.debug("Heal vnf start!")
390             logger.debug("do_heal: vnfmid=[%s],vnfInstanceId=[%s],request data=[%s]",
391                          vnfmid, vnfInstanceId, input_data)
392             statusCode, resp, location = do_lcmVnf(vnfmid, vnfInstanceId, input_data.data, "heal")
393             logger.debug("do_heal: response data=[%s]", resp)
394             logger.debug("Heal vnf end!")
395             ret = int(statusCode)
396             if ret == status.HTTP_404_NOT_FOUND:
397                 return Response(data=resp, status=status.HTTP_404_NOT_FOUND)
398             elif ret == status.HTTP_409_CONFLICT:
399                 return Response(data=resp, status=status.HTTP_409_CONFLICT)
400             response = Response(data=None, status=status.HTTP_202_ACCEPTED)
401             response["Location"] = location
402             return response
403         except GvnfmDriverException as e:
404             logger.error('Heal vnf failed, detail message: %s' % e.args[0])
405             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
406         except:
407             logger.error(traceback.format_exc())
408             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
409
410
411 class VnfPkgsInfo(APIView):
412     def get(request, *args, **kwargs):
413         try:
414             logger.debug("Enter %s", fun_name())
415             ret = req_by_msb("api/nslcm/v1/vnfpackage", "GET")
416             if ret[0] != 0:
417                 logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
418                 raise GvnfmDriverException('Failed to get vnfpkgs.')
419             resp = json.JSONDecoder().decode(ret[1])
420             return Response(data=resp, status=status.HTTP_200_OK)
421         except GvnfmDriverException as e:
422             logger.error('Get vnfpkgs failed, detail message: %s' % e.args[0])
423             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
424         except:
425             logger.error(traceback.format_exc())
426             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
427
428
429 class QuerySingleVnfLcmOpOcc(APIView):
430     @swagger_auto_schema(
431         responses={
432             status.HTTP_200_OK: VNFLCMOpOccSerializer(),
433             status.HTTP_500_INTERNAL_SERVER_ERROR: ""
434         }
435     )
436     def get(self, request, vnfmtype, vnfmid, lcmopoccid):
437         logger.debug("[%s]LCMOpOccId = %s", fun_name(), lcmopoccid)
438         try:
439             vnfm_info = get_vnfminfo_from_nslcm(vnfmid)
440             logger.debug("[get lcm op occ] vnfm_info=[%s]", vnfm_info)
441             ret = call_vnfm("api/vnflcm/v1/vnf_lcm_op_occs/%s" % lcmopoccid, "GET", vnfm_info)
442             if ret[0] != 0:
443                 logger.error("Status code is %s. detail is %s.", ret[2], ret[1])
444                 raise GvnfmDriverException("Failed to query vnf lcm op occ %s" % lcmopoccid)
445             resp_data = json.JSONDecoder().decode(ret[1])
446             vnf_lcm_op_occ_serializer = VNFLCMOpOccSerializer(data=resp_data)
447             if vnf_lcm_op_occ_serializer.is_valid():
448                 logger.debug("[%s]resp_data=%s" % (fun_name(), resp_data))
449                 return Response(data=vnf_lcm_op_occ_serializer.data, status=status.HTTP_200_OK)
450             else:
451                 raise GvnfmDriverException(vnf_lcm_op_occ_serializer.errors)
452         except GvnfmDriverException as e:
453             logger.error("Query vnflcmopocc failed, detail message: %s" % e.args[0])
454             return Response(data={'error': e.args[0]}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
455         except:
456             logger.error(traceback.format_exc())
457             return Response(data={'error': traceback.format_exc()}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
458
459
460 class Subscription(APIView):
461     @swagger_auto_schema(
462         request_body=LccnSubscriptionRequestSerializer(),
463         responses={
464             status.HTTP_201_CREATED: LccnSubscriptionSerializer(),
465             status.HTTP_303_SEE_OTHER: None,
466             status.HTTP_500_INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR"
467         }
468     )
469     def post(self, request, vnfmtype, vnfmid):
470         logger.debug("Subscription--post::> %s" % request.data)
471         logger.debug("Subscription begin!")
472         try:
473             lccn_subscription_request_serializer = LccnSubscriptionRequestSerializer(data=request.data)
474             if not lccn_subscription_request_serializer.is_valid():
475                 raise GvnfmDriverException(lccn_subscription_request_serializer.error_messages)
476             resp_data = do_subscription(request.data, vnfmid)
477             lccn_subscription_serializer = LccnSubscriptionSerializer(data=resp_data)
478             if not lccn_subscription_serializer.is_valid():
479                 logger.debug("[%s]resp_data=%s" % (fun_name(), resp_data))
480                 raise GvnfmDriverException(lccn_subscription_serializer.errors)
481             logger.debug("Subscription end!")
482             return Response(data=lccn_subscription_serializer.data, status=status.HTTP_201_CREATED)
483         except GvnfmDriverException as e:
484             logger.error(e.args[0])
485             return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
486         except Exception as e:
487             logger.error(e.args[0])
488             logger.error(traceback.format_exc())
489             return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
490
491
492 def call_vnfm(resource, method, vnfm_info, data=""):
493     ret = restcall.call_req(
494         base_url=ignorcase_get(vnfm_info, "url"),
495         # user=ignorcase_get(vnfm_info, "userName"),
496         # passwd=ignorcase_get(vnfm_info, "password"),
497         user="",
498         passwd="",
499         auth_type=restcall.rest_no_auth,
500         resource=resource,
501         method=method,
502         content=json.JSONEncoder().encode(data))
503     return ret
504
505
506 def mapping_conv(keyword_map, rest_return):
507     resp_data = {}
508     for param in keyword_map:
509         # if keyword_map[param]:
510         if isinstance(keyword_map[param], dict):
511             resp_data[param] = mapping_conv(keyword_map[param], ignorcase_get(rest_return, param))
512         else:
513             value = ignorcase_get(rest_return, param)
514             if value:
515                 resp_data[param] = value
516     return resp_data
517
518
519 def fun_name():
520     return "=========%s=========" % inspect.stack()[1][3]
521
522
523 def ignorcase_get(args, key):
524     if not key:
525         return ""
526     if not args:
527         return ""
528     if key in args:
529         return args[key]
530     for old_key in args:
531         if old_key.upper() == key.upper():
532             return args[old_key]
533     return ""
534
535
536 def get_vnfminfo_from_nslcm(vnfm_id):
537     logger.debug("[get_vnfminfo_from_nslcm] vnfm_id=[%s]", vnfm_id)
538     # ret = req_by_msb("api/aai-esr-server/v1/vnfms/%s" % vnfm_id, "GET")
539     ret = req_by_msb("api/nslcm/v1/vnfms/%s" % vnfm_id, "GET")
540     logger.debug("[get_vnfminfo_from_nslcm] response=%s", ret)
541     if ret[0] != 0:
542         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
543         raise GvnfmDriverException("Failed to query vnfm(%s) from nslcm." % vnfm_id)
544     return json.JSONDecoder().decode(ret[1])
545
546
547 def wait4job(vnfm_id, job_id, gracefulTerminationTimeout=1200, retry_count=60, interval_second=3):
548     logger.debug("[wait4job] vnfm_id=[%s],jobId=[%s],gracefulTerminationTimeout=[%s]",
549                  vnfm_id, job_id, gracefulTerminationTimeout)
550     count = 0
551     response_id, new_response_id = 0, 0
552     job_end_normal, job_timeout = False, True
553     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
554     logger.debug("[do_terminatevnf] vnfm_info=[%s]", vnfm_info)
555     while count < retry_count:
556         count = count + 1
557         time.sleep(interval_second)
558         ret = call_vnfm("api/vnflcm/v1/vnf_lc_ops/%s?responseId=%s" % (job_id, response_id), "GET", vnfm_info)
559         if ret[0] != 0:
560             logger.error("Failed to query job: %s:%s", ret[2], ret[1])
561             continue
562         job_result = json.JSONDecoder().decode(ret[1])
563         if "responseDescriptor" not in job_result:
564             logger.error("Job(%s) does not exist.", job_id)
565             continue
566         progress = str(job_result["responseDescriptor"]["progress"])
567         new_response_id = job_result["responseDescriptor"]["responseId"]
568         job_desc = job_result["responseDescriptor"]["statusDescription"]
569         if new_response_id != response_id:
570             logger.debug("%s:%s:%s", progress, new_response_id, job_desc)
571             response_id = new_response_id
572             count = 0
573         if progress == "255":
574             job_timeout = False
575             logger.error("Job(%s) failed: %s", job_id, job_desc)
576             break
577         elif progress == "100":
578             job_end_normal, job_timeout = True, False
579             logger.debug("Job(%s) ended normally,job_end_normal=[%s],job_timeout=[%s]",
580                          job_id, job_end_normal, job_timeout)
581             return {"success": "success"}
582     if job_timeout:
583         logger.error("Job(%s) timeout", job_id)
584     raise GvnfmDriverException("Fail to get job status!")
585
586
587 def do_createvnf(vnfm_id, data):
588     logger.debug("[%s] request.data=%s", fun_name(), data)
589     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
590     logger.debug("[do_createvnf] vnfm_info=[%s]", vnfm_info)
591     ret = call_vnfm("api/vnflcm/v1/vnf_instances", "POST", vnfm_info, data)
592     logger.debug("[%s] call_req ret=%s", fun_name(), ret)
593     if ret[0] != 0:
594         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
595         raise GvnfmDriverException('Failed to create vnf.')
596     return json.JSONDecoder().decode(ret[1])
597
598
599 def do_instvnf(vnfInstanceId, vnfm_id, data):
600     logger.debug("[%s] request.data=%s", fun_name(), data)
601     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
602     logger.debug("[do_instvnf] vnfm_info=[%s]", vnfm_info)
603     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s/instantiate" % vnfInstanceId, "POST", vnfm_info, data)
604     logger.debug("[%s] call_req ret=%s", fun_name(), ret)
605     if ret[0] != 0:
606         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
607         raise GvnfmDriverException('Failed to inst vnf.')
608     return json.JSONDecoder().decode(ret[1])
609
610
611 def do_terminatevnf(vnfm_id, vnfInstanceId, data):
612     logger.debug("[%s] request.data=%s", fun_name(), data)
613     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
614     logger.debug("[do_terminatevnf] vnfm_info=[%s]", vnfm_info)
615     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s/terminate" % vnfInstanceId, "POST", vnfm_info, data)
616     if ret[0] != 0:
617         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
618         raise GvnfmDriverException('Failed to terminate vnf.')
619     return json.JSONDecoder().decode(ret[1])
620
621
622 def do_deletevnf(vnfm_id, vnfInstanceId):
623     logger.debug("[%s] vnfm_id=%s, vnfInstanceId=%s", fun_name(), vnfm_id, vnfInstanceId)
624     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
625     logger.debug("[do_deletevnf] vnfm_info=[%s]", vnfm_info)
626     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s" % vnfInstanceId, "DELETE", vnfm_info)
627     if ret[0] != 0:
628         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
629         raise GvnfmDriverException('Failed to delete vnf.')
630     return ret[1]
631
632
633 def do_lcmVnf(vnfm_id, vnfInstanceId, data, lcmType):
634     logger.debug("[%s] request.data=%s", fun_name(), data)
635     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
636     logger.debug("[do_lcmVnf] vnfm_info=[%s]", vnfm_info)
637     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s/%s" % (vnfInstanceId, lcmType), "POST", vnfm_info, data)
638     if ret[0] != 0 and int(ret[2]) != status.HTTP_404_NOT_FOUND and int(ret[2]) != status.HTTP_409_CONFLICT:
639         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
640         raise GvnfmDriverException('Failed to Operate vnf.')
641     return (ret[2], json.JSONDecoder().decode(ret[1]) if ret[1] else {}, ret[3])
642
643
644 def do_queryvnf(data, vnfm_id, vnfInstanceId):
645     logger.debug("[%s] request.data=%s", fun_name(), data)
646     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
647     logger.debug("[do_deletevnf] vnfm_info=[%s]", vnfm_info)
648     ret = call_vnfm("api/vnflcm/v1/vnf_instances/%s" % vnfInstanceId, "GET", vnfm_info)
649     if ret[0] != 0:
650         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
651         raise GvnfmDriverException('Failed to query vnf.')
652     return json.JSONDecoder().decode(ret[1])
653
654
655 def do_subscription(data, vnfm_id):
656     logger.debug("[%s] request.data=%s", fun_name(), data)
657     vnfm_info = get_vnfminfo_from_nslcm(vnfm_id)
658     logger.debug("[do_subscription] vnfm_info=[%s]", vnfm_info)
659     ret = call_vnfm("api/vnflcm/v1/subscriptions", "POST", vnfm_info, data)
660     logger.debug("[%s] call_req ret=%s", fun_name(), ret)
661     if ret[0] != 0:
662         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
663         raise GvnfmDriverException('Failed to subscribe.')
664     return json.JSONDecoder().decode(ret[1])
665
666
667 class HealthCheckView(APIView):
668     @swagger_auto_schema(
669         responses={
670             status.HTTP_200_OK: 'Active'})
671     def get(self, request, format=None):
672         logger.debug("HealthCheck")
673         return Response({"status": "active"})