Trigger subscription in nslcm. 93/66793/3
authorlaili <lai.li@zte.com.cn>
Sat, 15 Sep 2018 08:26:26 +0000 (16:26 +0800)
committerlaili <lai.li@zte.com.cn>
Mon, 17 Sep 2018 03:19:20 +0000 (11:19 +0800)
Delete subscription when terminate vnf.

Change-Id: Ic7d94f3698b2bf73543f702d9ffbb41ceac26b7e
Issue-ID: VFC-1126
Signed-off-by: laili <lai.li@zte.com.cn>
lcm/ns_vnfs/biz/create_vnfs.py
lcm/ns_vnfs/biz/subscribe.py
lcm/ns_vnfs/biz/terminate_nfs.py
lcm/ns_vnfs/tests/tests.py
lcm/pub/database/models.py

index ec3cc31..ea75536 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2016 ZTE Corporation.
+# Copyright 2016-2018 ZTE Corporation.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -11,6 +11,7 @@
 # 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 json
 import logging
 import traceback
@@ -34,7 +35,7 @@ from lcm.pub.utils import restcall
 from lcm.ns_vnfs.const import VNF_STATUS, NFVO_VNF_INST_TIMEOUT_SECOND, INST_TYPE, INST_TYPE_NAME
 from lcm.ns_vnfs.biz.wait_job import wait_job_finish
 from lcm.pub.config.config import REG_TO_MSB_REG_PARAM, OOF_BASE_URL, OOF_PASSWD, OOF_USER
-from lcm.ns_vnfs.biz.subscribe import Subscription
+from lcm.ns_vnfs.biz.subscribe import SubscriptionCreation
 
 logger = logging.getLogger(__name__)
 
@@ -335,7 +336,7 @@ class CreateVnfs(Thread):
             'vnfInstanceId': self.vnfm_nf_inst_id,
             'vnfmId': self.vnfm_inst_id
         }
-        Subscription(data).do_biz()
+        SubscriptionCreation(data).do_biz()
 
     def write_vnf_creation_info(self):
         logger.debug("write_vnf_creation_info start")
index 71ef6cc..2a4a817 100644 (file)
 import json
 import logging
 
+from lcm.pub.database.models import SubscriptionModel
 from lcm.pub.exceptions import NSLCMException
 from lcm.pub.msapi.extsys import get_vnfm_by_id
 from lcm.pub.utils.restcall import req_by_msb
+from lcm.pub.utils.values import ignore_case_get
 
 logger = logging.getLogger(__name__)
 
 
-class Subscription(object):
+class SubscriptionCreation(object):
     def __init__(self, data):
         self.data = data
         self.vnf_instance_id = self.data['vnfInstanceId']
@@ -34,7 +36,7 @@ class Subscription(object):
     def do_biz(self):
         logger.debug('Start subscribing...')
         self.prepare_subscription_request_data()
-        self.subscribe_lccn_notification()
+        self.send_subscription_request()
         self.save_subscription_response_data()
         logger.debug('Subscribing has completed.')
 
@@ -80,12 +82,55 @@ class Subscription(object):
             }
         }
 
-    def subscribe_lccn_notification(self):
-        ret = req_by_msb('api/gvnfmdrvier/v1/%s/subscriptions' % self.vnfm_id, self.subscription_request_data)
+    def send_subscription_request(self):
+        ret = req_by_msb('api/gvnfmdrvier/v1/%s/subscriptions' % self.vnfm_id, 'POST', self.subscription_request_data)
         if ret[0] != 0:
             logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
             raise NSLCMException("Failed to subscribe from vnfm(%s)." % self.vnfm_id)
         self.subscription_response_data = json.JSONDecoder().decode(ret[1])
 
     def save_subscription_response_data(self):
-        pass
+        logger.debug("Save subscription[%s] to the database" % self.subscription_response_data['id'])
+        lccn_filter = self.subscription_response_data['filter']
+        SubscriptionModel.objects.create(
+            subscription_id=self.subscription_response_data['id'],
+            notification_types=json.dumps(lccn_filter['notificationTypes']),
+            operation_types=json.dumps(lccn_filter['operationTypes']),
+            operation_states=json.dumps(lccn_filter['operationStates']),
+            vnf_instance_filter=json.dumps(lccn_filter['vnfInstanceSubscriptionFilter']),
+            callback_uri=self.subscription_response_data['callbackUri'],
+            links=json.dumps(self.subscription_response_data['_links'])
+        )
+        logger.debug('Subscription[%s] has been created', self.subscription_response_data['id'])
+
+
+class SubscriptionDeletion(object):
+    def __init__(self, vnfm_id, vnf_instance_id):
+        self.vnfm_id = vnfm_id
+        self.vnf_instance_id = vnf_instance_id
+        self.subscription_id = None
+        self.subscription = None
+
+    def do_biz(self):
+        self.filter_subscription()
+        self.send_subscription_deletion_request()
+        self.delete_subscription_in_db()
+
+    def filter_subscription(self):
+        subscritptions = SubscriptionModel.objects.filter(vnf_instance_filter__contains=self.vnf_instance_id)
+        if not subscritptions.exists():
+            logger.debug("Subscription contains VNF(%s) does not exist." % self.vnf_instacne_id)
+        self.subscription = subscritptions.first()
+
+    def send_subscription_deletion_request(self):
+        if self.subscription:
+            self.subscription_id = ignore_case_get(self.subscription, 'id')
+            ret = req_by_msb('api/gvnfmdrvier/v1/%s/subscriptions/%s' % (self.vnfm_id, self.subscription_id), 'DELETE')
+            if ret[0] != 0:
+                logger.error('Status code is %s, detail is %s.', ret[2], ret[1])
+                raise NSLCMException("Failed to subscribe from vnfm(%s)." % self.vnfm_id)
+            logger.debug('Subscripton(%s) in vnfm(%s) has been deleted.' % (self.subscription, self.vnfm_id))
+
+    def delete_subscription_in_db(self):
+        if self.subscription:
+            self.subscription.delete()
index 98bc7d2..f921edd 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2016 ZTE Corporation.
+# Copyright 2016-2018 ZTE Corporation.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ from lcm.pub.utils.jobutil import JOB_MODEL_STATUS, JobUtil
 from lcm.pub.utils.values import ignore_case_get
 from lcm.ns_vnfs.const import VNF_STATUS, NFVO_VNF_INST_TIMEOUT_SECOND, INST_TYPE
 from lcm.ns_vnfs.biz.wait_job import wait_job_finish
+from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion
 
 logger = logging.getLogger(__name__)
 
@@ -53,6 +54,7 @@ class TerminateVnfs(threading.Thread):
             if REPORT_TO_AAI:
                 self.delete_vserver_in_aai()
                 self.delete_vnf_in_aai()
+            self.delete_subscription()
             self.delete_data_from_db()
         except NSLCMException as e:
             self.set_job_err(e.message)
@@ -128,6 +130,9 @@ class TerminateVnfs(threading.Thread):
             logger.error('VNF terminate failed on VNFM side.')
             raise NSLCMException('VNF terminate failed on VNFM side.')
 
+    def delete_subscription(self):
+        SubscriptionDeletion(self.vnfm_inst_id, self.vnf_inst_id).do_biz()
+
     def delete_data_from_db(self):
         NfInstModel.objects.filter(nfinstid=self.vnf_inst_id).delete()
         JobUtil.add_job_status(self.job_id, 100, 'vnf terminate success', 0)
index ba92e19..6669fbc 100644 (file)
@@ -18,7 +18,7 @@ import mock
 from django.test import TestCase, Client
 from rest_framework import status
 
-from lcm.pub.database.models import NfInstModel, JobModel, NSInstModel, VmInstModel, OOFDataModel
+from lcm.pub.database.models import NfInstModel, JobModel, NSInstModel, VmInstModel, OOFDataModel, SubscriptionModel
 from lcm.pub.exceptions import NSLCMException
 from lcm.pub.utils import restcall
 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS
@@ -28,6 +28,7 @@ from lcm.pub.utils.values import ignore_case_get
 from lcm.ns_vnfs.biz.create_vnfs import CreateVnfs
 from lcm.ns_vnfs.biz.heal_vnfs import NFHealService
 from lcm.ns_vnfs.biz.scale_vnfs import NFManualScaleService
+from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion
 from lcm.ns_vnfs.biz.terminate_nfs import TerminateVnfs
 from lcm.ns_vnfs.const import VNF_STATUS, INST_TYPE
 from lcm.ns_vnfs.biz import create_vnfs
@@ -257,7 +258,8 @@ class TestTerminateVnfViews(TestCase):
         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
 
     @mock.patch.object(restcall, 'call_req')
-    def test_terminate_vnf(self, mock_call_req):
+    @mock.patch.object(SubscriptionDeletion, 'send_subscription_deletion_request')
+    def test_terminate_vnf(self, mock_send_subscription_deletion_request, mock_call_req):
         job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, self.nf_inst_id)
 
         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
@@ -266,6 +268,43 @@ class TestTerminateVnfViews(TestCase):
         else:
             self.failUnlessEqual(1, 0)
 
+        notification_types = ["VnfLcmOperationOccurrenceNotification"],
+        operation_types = [
+            "INSTANTIATE",
+            "SCALE",
+            "SCALE_TO_LEVEL",
+            "CHANGE_FLAVOUR",
+            "TERMINATE",
+            "HEAL",
+            "OPERATE",
+            "CHANGE_EXT_CONN",
+            "MODIFY_INFO"
+        ],
+        operation_states = [
+            "STARTING",
+            "PROCESSING",
+            "COMPLETED",
+            "FAILED_TEMP",
+            "FAILED",
+            "ROLLING_BACK",
+            "ROLLED_BACK"
+        ],
+        vnf_instance_subscription_filter = {
+            "vnfdIds": [],
+            "vnfInstanceIds": '1',
+            "vnfInstanceNames": [],
+            "vnfProductsFromProviders": {}
+        }
+        SubscriptionModel.objects.create(
+            subscription_id='1',
+            notification_types=json.dumps(notification_types),
+            operation_types=json.dumps(operation_types),
+            operation_states=json.dumps(operation_states),
+            vnf_instance_filter=json.dumps(vnf_instance_subscription_filter),
+            # callback_uri,
+            # links=json.dumps(...)
+        )
+
         vnf_info = {
             "vnf-id": "vnf-id-test111",
             "vnf-name": "vnf-name-test111",
@@ -317,6 +356,7 @@ class TestTerminateVnfViews(TestCase):
 
         def side_effect(*args):
             return mock_vals[args[4]]
+
         mock_call_req.side_effect = side_effect
 
         req_data = {
index 7c6fee7..f1aa57a 100644 (file)
@@ -330,3 +330,16 @@ class OOFDataModel(models.Model):
     cloud_owner = models.CharField(db_column='CLOUDOWNER', max_length=100, null=True, blank=True)
     cloud_region_id = models.CharField(db_column='CLOUDREGIONID', max_length=255, null=True, blank=True)
     vdu_info = models.TextField(db_column='VDUINFO', max_length=65535, null=True, blank=True)
+
+
+class SubscriptionModel(models.Model):
+    class Meta:
+        db_table = 'NFVO_SUBSCRIPTION'
+
+    subscription_id = models.CharField(db_column='SUBSCRIPTIONID', max_length=255, primary_key=True)
+    vnf_instance_filter = models.TextField(db_column='VNFINSTANCEFILTER', null=True)
+    notification_types = models.TextField(db_column='NOTIFICATIONTYPES', null=True)
+    operation_types = models.TextField(db_column='OPERATIONTYPES', null=True)
+    operation_states = models.TextField(db_column='OPERATIONSTATES', null=True)
+    callback_uri = models.CharField(db_column='CALLBACKURI', max_length=255)
+    links = models.TextField(db_column='LINKS', max_length=20000)