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