add function of update 31/68331/3
authortianxing <15210838572@139.com>
Fri, 21 Sep 2018 03:36:45 +0000 (11:36 +0800)
committerTian Xing <15210838572@139.com>
Mon, 8 Oct 2018 03:22:47 +0000 (03:22 +0000)
Change-Id: I7d6107d1f7210ed460c82b8f9a76a4d6bf8566d8
Issue-ID: VFC-1139
Signed-off-by: tianxing <15210838572@139.com>
lcm/ns/biz/ns_update.py [new file with mode: 0644]
lcm/ns/serializers/update_serializers.py
lcm/ns/urls.py
lcm/ns/views/update_ns_view.py [new file with mode: 0644]

diff --git a/lcm/ns/biz/ns_update.py b/lcm/ns/biz/ns_update.py
new file mode 100644 (file)
index 0000000..cb00ced
--- /dev/null
@@ -0,0 +1,150 @@
+# Copyright (c) 2018, CMCC Technologies Co., Ltd.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+import threading
+import traceback
+import datetime
+import time
+
+from lcm.ns.const import NS_INST_STATUS
+from lcm.pub.database.models import JobModel, NSInstModel
+from lcm.ns_vnfs.biz.update_vnfs import NFOperateService
+from lcm.pub.exceptions import NSLCMException
+from lcm.pub.utils.jobutil import JobUtil, JOB_MODEL_STATUS
+from lcm.pub.utils.values import ignore_case_get
+from lcm.pub.utils.enumutil import enum
+
+JOB_ERROR = 255
+logger = logging.getLogger(__name__)
+OPERATIONAL_STATES = enum(STOPPED='STOPPED', STARTED='STARTED')
+STOP_TYPE = enum(GRACEFUL='GRACEFUL', FORCEFUL='FORCEFUL')
+
+
+class NSUpdateService(threading.Thread):
+    def __init__(self, ns_instance_id, request_data, job_id):
+        super(NSUpdateService, self).__init__()
+        self.ns_instance_id = ns_instance_id
+        self.request_data = request_data
+        self.job_id = job_id
+
+        self.update_type = ''
+        self.operate_vnf_data = ''
+
+    def run(self):
+        try:
+            self.do_biz()
+        except NSLCMException as e:
+            logger.error(traceback.format_exc())
+            JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message)
+        except:
+            logger.error(traceback.format_exc())
+            JobUtil.add_job_status(self.job_id, JOB_ERROR, 'ns update fail')
+
+    def do_biz(self):
+        self.update_job(1, desc='ns update start')
+        self.get_and_check_params()
+        self.update_ns_status(NS_INST_STATUS.UPDATING)
+        self.do_update()
+        self.update_ns_status(NS_INST_STATUS.ACTIVE)
+        self.update_job(100, desc='ns update success')
+
+    def get_and_check_params(self):
+        ns_info = NSInstModel.objects.filter(id=self.ns_instance_id)
+        if not ns_info:
+            raise NSLCMException(
+                'NS [id=%s] does not exist' % self.ns_instance_id)
+
+        self.update_type = ignore_case_get(self.request_data, "updateType")
+        if not self.update_type:
+            raise NSLCMException(
+                'UpdateType parameter does not exist or value incorrect.')
+
+    def do_update(self):
+        if self.update_type == "OPERATE_VNF":
+            self.operate_vnf_data = ignore_case_get(
+                self.request_data, "operateVnfData")
+            if not self.operate_vnf_data:
+                raise NSLCMException(
+                    'OperateVnfData does not exist or value is incorrect.')
+            for vnf_update_data in self.operate_vnf_data:
+                vnf_update_params = self.prepare_update_params(vnf_update_data)
+                status = self.do_vnf_update(vnf_update_params, 15)
+                if status is JOB_MODEL_STATUS.FINISHED:
+                    logger.info(
+                        'nf[%s] update handle end' % vnf_update_params.get('vnfInstanceId'))
+                    self.update_job(90,
+                                    desc='nf[%s] update handle end'
+                                         % vnf_update_params.get('vnfInstanceId'))
+                else:
+                    raise NSLCMException('nf update failed')
+        else:
+            raise NSLCMException('Method update.')
+
+    def do_vnf_update(self, vnf_update_params, progress):
+        vnf_instance_id = vnf_update_params.get('vnfInstanceId')
+        nf_service = NFOperateService(vnf_instance_id, vnf_update_params)
+        nf_service.start()
+        self.update_job(progress, desc='nf[%s] update handle start' % vnf_instance_id)
+        status = self.wait_job_finish(nf_service.job_id)
+        return status
+
+    @staticmethod
+    def prepare_update_params(vnf_data):
+        vnf_instance_id = ignore_case_get(vnf_data, 'vnfInstanceId')
+        if not vnf_instance_id:
+            raise NSLCMException(
+                'VnfInstanceId does not exist or value is incorrect.')
+
+        change_state_to = ignore_case_get(vnf_data, 'changeStateTo')
+        if not change_state_to:
+            raise NSLCMException(
+                'ChangeStateTo does not exist or value is incorrect.')
+        Stop_Type = ''
+        graceful_stop_timeout = ''
+        operational_states = ignore_case_get(change_state_to, 'OperationalStates')
+        if operational_states == OPERATIONAL_STATES.STOPPED:
+            stop_type = ignore_case_get(vnf_data, 'stopType')
+            Stop_Type = ignore_case_get(stop_type, 'StopType')
+            if Stop_Type == STOP_TYPE.GRACEFUL:
+                graceful_stop_timeout = ignore_case_get(vnf_data, 'gracefulStopTimeout')
+
+        result = {
+            "vnfInstanceId": vnf_instance_id,
+            "changeStateTo": operational_states,
+            "stopType": Stop_Type,
+            "gracefulStopTimeout": graceful_stop_timeout
+        }
+        return result
+
+    @staticmethod
+    def wait_job_finish(sub_job_id, timeout=3600):
+        query_interval = 2
+        start_time = end_time = datetime.datetime.now()
+        while (end_time - start_time).seconds < timeout:
+            job_result = JobModel.objects.get(jobid=sub_job_id)
+            time.sleep(query_interval)
+            end_time = datetime.datetime.now()
+            if job_result.progress == 100:
+                return JOB_MODEL_STATUS.FINISHED
+            elif job_result.progress > 100:
+                return JOB_MODEL_STATUS.ERROR
+            else:
+                continue
+        return JOB_MODEL_STATUS.TIMEOUT
+
+    def update_job(self, progress, desc=''):
+        JobUtil.add_job_status(self.job_id, progress, desc)
+
+    def update_ns_status(self, status):
+        NSInstModel.objects.filter(id=self.ns_instance_id).update(status=status)
index 80d506e..fc3b6fb 100644 (file)
@@ -147,7 +147,7 @@ class OperationalStatesSerializer(serializers.Serializer):
 
 
 class StopTypeSerializer(serializers.Serializer):
-    StopType = serializers.CharField(help_text="Type of stop", choices=["FORCEFUL", "GRACEFUL"])
+    StopType = serializers.ChoiceField(help_text="Type of stop", choices=["FORCEFUL", "GRACEFUL"])
 
 
 class OperateVnfDataSerializer(serializers.Serializer):
index 4322d76..53c4249 100644 (file)
@@ -18,6 +18,7 @@ from lcm.ns.views.create_ns_view import CreateNSView
 from lcm.ns.views.inst_ns_view import NSInstView
 from lcm.ns.views.term_ns_view import TerminateNSView
 from lcm.ns.views.heal_ns_view import NSHealView
+from lcm.ns.views.update_ns_view import NSUpdateView
 from lcm.ns.views.get_del_ns_view import NSDetailView
 from lcm.ns.views.inst_ns_post_deal_view import NSInstPostDealView
 from lcm.ns.views.scale_ns_views import NSManualScaleView
@@ -31,10 +32,10 @@ urlpatterns = [
     url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)$', NSDetailView.as_view()),
     url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/postdeal$', NSInstPostDealView.as_view()),
     url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/scale$', NSManualScaleView.as_view()),
-    url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/heal$', NSHealView.as_view())
+    url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/heal$', NSHealView.as_view()),
 
     # SOL005 URL API definition TODO
-
+    url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/update$', NSUpdateView.as_view())
 ]
 
 urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/lcm/ns/views/update_ns_view.py b/lcm/ns/views/update_ns_view.py
new file mode 100644 (file)
index 0000000..45aa273
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright (c) 2018, CMCC Technologies Co., Ltd.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.views import APIView
+from drf_yasg.utils import swagger_auto_schema
+
+from lcm.ns.biz.ns_update import NSUpdateService
+from lcm.ns.serializers.ns_serializers import NsOperateJobSerializer
+from lcm.ns.serializers.update_serializers import UpdateNsReqSerializer
+from lcm.pub.exceptions import NSLCMException
+from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE
+
+logger = logging.getLogger(__name__)
+
+
+class NSUpdateView(APIView):
+    @swagger_auto_schema(
+        request_body=UpdateNsReqSerializer(),
+        responses={
+            status.HTTP_202_ACCEPTED: NsOperateJobSerializer(),
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
+        }
+    )
+    def post(self, request, ns_instance_id):
+        try:
+            logger.debug("Enter UpdateNSView::post %s, %s", request.data, ns_instance_id)
+            req_serializer = UpdateNsReqSerializer(data=request.data)
+            if not req_serializer.is_valid():
+                raise NSLCMException(req_serializer.errors)
+
+            job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, ns_instance_id)
+            NSUpdateService(ns_instance_id, request.data, job_id).start()
+
+            resp_serializer = NsOperateJobSerializer(data={'jobId': job_id})
+            if not resp_serializer.is_valid():
+                raise NSLCMException(resp_serializer.errors)
+
+            logger.debug("Leave UpdateNSView::post ret=%s", resp_serializer.data)
+            return Response(data=resp_serializer.data, status=status.HTTP_202_ACCEPTED)
+        except Exception as e:
+            logger.error("Exception in UpdateNSView: %s", e.message)
+            return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)