Fix vfc lcm vnf operations unit tests
[vfc/nfvo/lcm.git] / lcm / ns / vnfs / terminate_nfs.py
1 # Copyright 2016 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 import logging
15 import traceback
16 import json
17
18 import threading
19
20 from lcm.ns.vnfs.wait_job import wait_job_finish
21 from lcm.pub.database.models import NfInstModel
22 from lcm.ns.vnfs.const import VNF_STATUS, NFVO_VNF_INST_TIMEOUT_SECOND
23 from lcm.pub.msapi.aai import query_vnf_aai, delete_vnf_aai
24 from lcm.pub.utils.values import ignore_case_get
25 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS, JobUtil
26 from lcm.pub.exceptions import NSLCMException
27 from lcm.pub.msapi.vnfmdriver import send_nf_terminate_request
28 from lcm.pub.msapi import resmgr
29
30 logger = logging.getLogger(__name__)
31
32
33 class TerminateVnfs(threading.Thread):
34     def __init__(self, data, vnf_inst_id, job_id):
35         threading.Thread.__init__(self)
36         self.vnf_inst_id = vnf_inst_id
37         self.job_id = job_id
38         self.vnfm_inst_id = ''
39         self.vnf_uuid = ''
40         self.vnfm_job_id = ''
41         self.terminationType = data['terminationType']
42         self.gracefulTerminationTimeout = data['gracefulTerminationTimeout']
43         self.initdata()
44
45     def run(self):
46         try:
47             self.check_nf_valid()
48             self.send_nf_terminate_to_vnfmDriver()
49             self.wait_vnfm_job_finish()
50             self.send_terminate_vnf_to_resMgr()
51             self.delete_data_from_db()
52             self.delete_vnf_in_aai()
53         except NSLCMException as e:
54             self.exception(e.message)
55         except Exception:
56             logger.error(traceback.format_exc())
57             self.exception('unexpected exception')
58
59     def set_vnf_status(self, vnf_inst_info):
60         vnf_status = vnf_inst_info.status
61         if (vnf_status == VNF_STATUS.TERMINATING):
62             logger.info('[VNF terminate] VNF is dealing by other application,try again later.')
63             raise NSLCMException('[VNF terminate] VNF is dealing by other application,try again later.')
64         else:
65             vnf_inst_info.status = VNF_STATUS.TERMINATING
66             vnf_inst_info.save()
67
68     def check_vnf_is_exist(self):
69         vnf_inst = NfInstModel.objects.filter(nfinstid=self.vnf_inst_id)
70         if not vnf_inst.exists():
71             logger.warning('[VNF terminate] Vnf terminate [%s] is not exist.' % self.vnf_inst_id)
72             return None
73         return vnf_inst[0]
74
75     def add_progress(self, progress, status_decs, error_code=""):
76         JobUtil.add_job_status(self.job_id, progress, status_decs, error_code)
77
78     def initdata(self):
79         vnf_inst_info = self.check_vnf_is_exist()
80         if not vnf_inst_info:
81             self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished")
82         self.add_progress(2, "GET_VNF_INST_SUCCESS")
83         self.vnfm_inst_id = vnf_inst_info.vnfm_inst_id
84         self.vnf_uuid = vnf_inst_info.mnfinstid
85         if not self.vnf_uuid:
86             self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished")
87
88     def check_nf_valid(self):
89         vnf_inst = NfInstModel.objects.filter(nfinstid=self.vnf_inst_id)
90         if not vnf_inst.exists():
91             logger.warning('[VNF terminate] Vnf instance [%s] is not exist.' % self.vnf_inst_id)
92             raise NSLCMException('[VNF terminate] Vnf instance is not exist.')
93         if not vnf_inst:
94             self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished")
95             raise NSLCMException('[VNF terminate] Vnf instance is not exist.')
96         self.set_vnf_status(vnf_inst[0])
97
98     def exception(self, error_msg):
99         logger.error('VNF Terminate failed, detail message: %s' % error_msg)
100         NfInstModel.objects.filter(nfinstid=self.vnf_inst_id).update(status=VNF_STATUS.FAILED)
101         JobUtil.add_job_status(self.job_id, 255, 'VNF Terminate failed, detail message: %s' % error_msg, 0)
102
103     def send_nf_terminate_to_vnfmDriver(self):
104         req_param = json.JSONEncoder().encode({
105             'terminationType': self.terminationType, 
106             'gracefulTerminationTimeout': self.gracefulTerminationTimeout})
107         rsp = send_nf_terminate_request(self.vnfm_inst_id, self.vnf_uuid, req_param)
108         self.vnfm_job_id = ignore_case_get(rsp, 'jobId')
109
110     def send_terminate_vnf_to_resMgr(self):
111         resmgr.terminate_vnf(self.vnf_inst_id)
112
113     def wait_vnfm_job_finish(self):
114         if not self.vnfm_job_id:
115             logger.warn("No Job, need not wait")
116             return
117         ret = wait_job_finish(vnfm_id=self.vnfm_inst_id, vnfo_job_id=self.job_id, 
118             vnfm_job_id=self.vnfm_job_id, progress_range=[10, 90],
119             timeout=NFVO_VNF_INST_TIMEOUT_SECOND)
120
121         if ret != JOB_MODEL_STATUS.FINISHED:
122             logger.error('VNF terminate failed on VNFM side.')
123             raise NSLCMException('VNF terminate failed on VNFM side.')
124
125     def delete_data_from_db(self):
126         NfInstModel.objects.filter(nfinstid=self.vnf_inst_id).delete()
127         JobUtil.add_job_status(self.job_id, 100, 'vnf terminate success', 0)
128
129     def delete_vnf_in_aai(self):
130         logger.debug("TerminateVnfs::delete_vnf_in_aai::delete vnf instance[%s] in aai." % self.vnf_inst_id)
131
132         # query vnf instance in aai, get resource_version
133         customer_info = query_vnf_aai(self.vnf_inst_id)
134         resource_version = customer_info["resource-version"]
135
136         # delete vnf instance from aai
137         resp_data, resp_status = delete_vnf_aai(self.vnf_inst_id, resource_version)
138         if resp_data:
139             logger.debug("Fail to delete vnf instance[%s] from aai, resp_status: [%s]." % (self.vnf_inst_id, resp_status))
140         else:
141             logger.debug(
142                 "Success to delete vnf instance[%s] from aai, resp_status: [%s]." % (self.vnf_inst_id, resp_status))