Merge "Add thread in waiting delete vnf"
[vfc/nfvo/lcm.git] / lcm / ns / biz / scale_aspect.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 copy
16 import json
17 import logging
18 import os
19
20 from lcm.pub.database.models import NSInstModel
21 from lcm.pub.database.models import NfInstModel
22 from lcm.pub.utils.values import ignore_case_get
23 from lcm.ns_vnfs.enum import VNF_STATUS
24
25 logger = logging.getLogger(__name__)
26
27 scale_vnf_data_mapping = {
28     "vnfInstanceId": "",
29     "scaleByStepData": {
30         "type": "",
31         "aspectId": "",
32         "numberOfSteps": ""
33     }
34 }
35
36
37 def mapping_conv(keyword_map, rest_return):
38     resp_data = {}
39     for param in keyword_map:
40         if keyword_map[param]:
41             if isinstance(keyword_map[param], dict):
42                 resp_data[param] = mapping_conv(
43                     keyword_map[param], ignore_case_get(
44                         rest_return, param))
45             else:
46                 resp_data[param] = ignore_case_get(rest_return, param)
47     return resp_data
48
49
50 def get_vnf_scale_info(filename, ns_instanceId, aspect, step):
51     json_data = get_json_data(filename)
52     scale_options = ignore_case_get(json_data, "scale_options")
53     for i in range(scale_options.__len__()):
54         ns_scale_option = scale_options[i]
55         if (ignore_case_get(ns_scale_option, "ns_instanceId") == ns_instanceId) \
56                 and (ignore_case_get(ns_scale_option, "ns_scale_aspect") == aspect):
57             ns_scale_info_list = ignore_case_get(
58                 ns_scale_option, "ns_scale_info_list")
59             for j in range(ns_scale_info_list.__len__()):
60                 ns_scale_info = ns_scale_info_list[j]
61                 if ns_scale_info["step"] == step:
62                     return ns_scale_info["vnf_scale_info"]
63
64     return None
65
66
67 def get_vnf_instance_id_list(vnfd_id):
68     kwargs = {}
69     kwargs['package_id'] = vnfd_id
70     kwargs['status'] = VNF_STATUS.ACTIVE
71
72     nf_model_list = NfInstModel.objects.filter(**kwargs)
73     vnf_instance_id_list = list()
74     nf_model_len = nf_model_list.__len__()
75     if nf_model_len == 0:
76         logger.error("No VNF instances found(vnfd_id=%s)" % vnfd_id)
77     else:
78         for i in range(nf_model_len):
79             vnf_instance_id_list.append(nf_model_list[i].nfinstid)
80
81     return vnf_instance_id_list
82
83
84 def get_json_data(filename):
85     f = open(filename)
86     json_str = f.read()
87     data = json.JSONDecoder().decode(json_str)
88     f.close()
89     return data
90
91
92 def check_scale_list(vnf_scale_list, ns_instanceId, aspect, step):
93     if vnf_scale_list is None or vnf_scale_list.__len__() == 0:
94         logger.debug(
95             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
96             (ns_instanceId, aspect, step))
97         raise Exception(
98             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
99             (ns_instanceId, aspect, step))
100     else:
101         return vnf_scale_list
102
103
104 def get_scale_vnf_data_list(filename, ns_instanceId, aspect, step, scale_type):
105
106     vnf_scale_list = get_vnf_scale_info(filename, ns_instanceId, aspect, step)
107     check_scale_list(vnf_scale_list, ns_instanceId, aspect, step)
108     scaleVnfDataList = set_scaleVnfData_type(vnf_scale_list, scale_type)
109     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
110     return scaleVnfDataList
111
112
113 # Get the nsd id according to the ns instance id.
114 def get_nsdId(ns_instanceId):
115     if NSInstModel.objects.filter(id=ns_instanceId):
116         nsd_id = NSInstModel.objects.filter(id=ns_instanceId)[0].nsd_id
117         return nsd_id
118
119     return None
120
121
122 def check_and_set_params(scaleNsData, ns_InstanceId):
123     if scaleNsData is None:
124         raise Exception("Error! scaleNsData in the request is Empty!")
125
126     scaleNsByStepsData = scaleNsData["scaleNsByStepsData"]  # scaleNsData[0]["scaleNsByStepsData"][0]
127     if scaleNsByStepsData is None:
128         raise Exception("Error! scaleNsByStepsData in the request is Empty!")
129
130     aspect = scaleNsByStepsData["aspectId"]
131     numberOfSteps = scaleNsByStepsData["numberOfSteps"]
132     scale_type = scaleNsByStepsData["scalingDirection"]
133
134     return aspect, numberOfSteps, scale_type
135
136
137 def get_scale_vnf_data(scaleNsData, ns_InstanceId):
138     curdir_path = os.path.dirname(
139         os.path.dirname(
140             os.path.dirname(
141                 os.path.abspath(__file__))))
142     filename = curdir_path + "/ns/data/scalemapping.json"
143     logger.debug("filename = %s" % filename)
144     aspect, numberOfSteps, scale_type = check_and_set_params(
145         scaleNsData, ns_InstanceId)
146     return get_scale_vnf_data_list(
147         filename,
148         ns_InstanceId,
149         aspect,
150         numberOfSteps,
151         scale_type)
152
153
154 # Get scaling vnf data info list according to the ns instance id and request ScaleNsData.
155 def get_scale_vnf_data_info_list(scaleNsData, ns_InstanceId):
156     # Gets the nsd id accordign to the ns instance id.
157     nsd_id = get_nsdId(ns_InstanceId)
158
159     # Gets the scalingmap json data from the package according to the ns instance id.
160     # scalingmap_json = catalog.get_scalingmap_json_package(ns_InstanceId)
161     base_path = os.path.dirname(
162         os.path.dirname(
163             os.path.dirname(
164                 os.path.abspath(__file__)
165             )
166         )
167     )
168     scalingmap_filename = base_path + "/ns/data/scalemapping.json"
169     scalingmap_json = get_json_data(scalingmap_filename)
170
171     # Gets and checks the values of parameters.
172     aspect, numberOfSteps, scale_type = check_and_set_params(
173         scaleNsData, ns_InstanceId)
174
175     # Firstly, gets the scaling vnf data info list from the scaling map json data.
176     scale_vnf_data_info_list_from_json = get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, numberOfSteps)
177     check_scale_list(scale_vnf_data_info_list_from_json, ns_InstanceId, aspect, numberOfSteps)
178
179     # Secondly, adds the property of vnfInstanceId to the list according to the vnfd id.
180     scale_vnf_data_info_list = set_scacle_vnf_instance_id(scale_vnf_data_info_list_from_json)
181     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
182
183     # Lastly, adds the property of type to the list acoording to the request ScaleNsData.
184     scale_vnf_data_info_list = set_scaleVnfData_type(scale_vnf_data_info_list, scale_type)
185     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
186
187     return scale_vnf_data_info_list
188
189
190 # Get the vnf scaling info from the scaling_map.json according to the ns package id.
191 def get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, step):
192     scale_options = ignore_case_get(scalingmap_json, "scale_options")
193     for i in range(scale_options.__len__()):
194         ns_scale_option = scale_options[i]
195         if (ignore_case_get(ns_scale_option, "nsd_id") == nsd_id) and (
196                 ignore_case_get(ns_scale_option, "ns_scale_aspect") == aspect):
197             ns_scale_info_list = ignore_case_get(
198                 ns_scale_option, "ns_scale_info")
199             for j in range(ns_scale_info_list.__len__()):
200                 ns_scale_info = ns_scale_info_list[j]
201                 if ns_scale_info["step"] == step:
202                     vnf_scale_info_list = ns_scale_info["vnf_scale_info"]
203
204                     return vnf_scale_info_list
205
206     logger.error("get_scale_vnf_data_from_json method retuan null")
207     return None
208
209
210 # Gets the vnf instance id according to the vnfd_id and modify the list of scaling vnf info accrodingly.
211 def set_scacle_vnf_instance_id(vnf_scale_info_list):
212     scale_vnf_data_info_list = []
213     for i in range(vnf_scale_info_list.__len__()):
214         vnf_scale_info = vnf_scale_info_list[i]
215         vnfd_id = vnf_scale_info["vnfd_id"]
216         vnf_instance_id_list = get_vnf_instance_id_list(vnfd_id)
217         index = 0
218         while index < vnf_instance_id_list.__len__():
219             copy_vnf_scale_info = copy.deepcopy(vnf_scale_info)
220             copy_vnf_scale_info.pop("vnfd_id")
221             copy_vnf_scale_info["vnfInstanceId"] = vnf_instance_id_list[index]
222             index += 1
223             scale_vnf_data_info_list.append(copy_vnf_scale_info)
224
225     return scale_vnf_data_info_list
226
227
228 # Sets the scaling type of vnf data info list.
229 def set_scaleVnfData_type(vnf_scale_list, scale_type):
230     logger.debug(
231         "vnf_scale_list = %s, type = %s" %
232         (vnf_scale_list, scale_type))
233     scaleVnfDataList = []
234     if vnf_scale_list is not None:
235         for i in range(vnf_scale_list.__len__()):
236             scaleVnfData = copy.deepcopy(scale_vnf_data_mapping)
237             scaleVnfData["vnfInstanceId"] = vnf_scale_list[i]["vnfInstanceId"]
238             scaleVnfData["scaleByStepData"]["type"] = scale_type
239             scaleVnfData["scaleByStepData"]["aspectId"] = vnf_scale_list[i]["vnf_scaleAspectId"]
240             scaleVnfData["scaleByStepData"]["numberOfSteps"] = vnf_scale_list[i]["numberOfSteps"]
241             scaleVnfDataList.append(scaleVnfData)
242     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
243     return scaleVnfDataList