aboutsummaryrefslogtreecommitdiffstats
path: root/lcm/ns_pnfs
diff options
context:
space:
mode:
authormaopengzhang <zhang.maopeng1@zte.com.cn>2018-09-17 16:55:34 +0800
committermaopengzhang <zhang.maopeng1@zte.com.cn>2018-09-17 20:52:00 +0800
commitdb610a8280b3922b64eef965e3707444885f8002 (patch)
tree09bc36d551dd53b652867d10dede89015734e603 /lcm/ns_pnfs
parent48f7b3d0d6fc76f6949b0608465267325237c00c (diff)
Support PNF In NSLCM
Support PNF in NSLCM Change-Id: I0e1d28d8f574ca38c6e99c74617e6dc91c6403ad Issue-ID: VFC-1102 Signed-off-by: maopengzhang <zhang.maopeng1@zte.com.cn>
Diffstat (limited to 'lcm/ns_pnfs')
-rw-r--r--lcm/ns_pnfs/__init__.py13
-rw-r--r--lcm/ns_pnfs/biz/__init__.py13
-rw-r--r--lcm/ns_pnfs/biz/active_pnf.py27
-rw-r--r--lcm/ns_pnfs/biz/create_pnf.py71
-rw-r--r--lcm/ns_pnfs/biz/delete_pnf.py34
-rw-r--r--lcm/ns_pnfs/biz/get_pnf.py33
-rw-r--r--lcm/ns_pnfs/serializers/__init__.py13
-rw-r--r--lcm/ns_pnfs/serializers/pnf_serializer.py28
-rw-r--r--lcm/ns_pnfs/tests/__init__.py13
-rw-r--r--lcm/ns_pnfs/tests/test_create_pnf.py90
-rw-r--r--lcm/ns_pnfs/tests/test_delete_pnf.py58
-rw-r--r--lcm/ns_pnfs/tests/test_get_pnf.py99
-rw-r--r--lcm/ns_pnfs/urls.py24
-rw-r--r--lcm/ns_pnfs/views/__init__.py13
-rw-r--r--lcm/ns_pnfs/views/pnf_view.py119
15 files changed, 648 insertions, 0 deletions
diff --git a/lcm/ns_pnfs/__init__.py b/lcm/ns_pnfs/__init__.py
new file mode 100644
index 00000000..342c2a8c
--- /dev/null
+++ b/lcm/ns_pnfs/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 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.
+# 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.
diff --git a/lcm/ns_pnfs/biz/__init__.py b/lcm/ns_pnfs/biz/__init__.py
new file mode 100644
index 00000000..342c2a8c
--- /dev/null
+++ b/lcm/ns_pnfs/biz/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 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.
+# 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.
diff --git a/lcm/ns_pnfs/biz/active_pnf.py b/lcm/ns_pnfs/biz/active_pnf.py
new file mode 100644
index 00000000..3a7ff860
--- /dev/null
+++ b/lcm/ns_pnfs/biz/active_pnf.py
@@ -0,0 +1,27 @@
+# Copyright 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.
+# 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.
+from lcm.pub.msapi.emsdriver import send_active_pnf_request
+
+
+class ActivePnf(object):
+ def __init__(self, ems_id, pnf_id, active_data):
+ self.ems_id = ems_id
+ self.pnf_id = pnf_id
+ self.data = active_data
+
+ def do_biz(self):
+ self.active_pnf()
+
+ def active_pnf(self):
+ return send_active_pnf_request(self.ems_id, self.pnf_id, self.data)
diff --git a/lcm/ns_pnfs/biz/create_pnf.py b/lcm/ns_pnfs/biz/create_pnf.py
new file mode 100644
index 00000000..c9207135
--- /dev/null
+++ b/lcm/ns_pnfs/biz/create_pnf.py
@@ -0,0 +1,71 @@
+# Copyright 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.
+# 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 lcm.pub.database.models import PNFInstModel
+from lcm.pub.exceptions import NSLCMException
+from lcm.pub.msapi.sdc_run_catalog import query_pnf_descriptor
+from lcm.ns_pnfs.biz.get_pnf import GetPnf
+
+logger = logging.getLogger(__name__)
+
+
+class CreatePnf(object):
+ def __init__(self, data):
+ self.pnfId = data.get("pnfId"),
+ self.pnfName = data.get("pnfName"),
+ self.pnfdId = data.get("pnfdId"),
+ self.pnfdInfoId = data.get("pnfdInfoId"),
+ self.pnfProfileId = data.get("pnfProfileId"),
+ self.cpInfo = data.get("cpInfo", "")
+ self.emsId = data.get("emsId", "")
+ self.nsInstances = data.get("nsInstances")
+
+ def do_biz(self):
+ self.check_pnfd_valid()
+ self.build_cpInfo()
+ self.build_emsId()
+ self.create_pnf_inst()
+ logger.debug("CreatePnf::do_biz::pnfId=%s" % self.pnfId)
+ return GetPnf({"pnfId": self.pnfId}, True).do_biz()
+
+ def check_pnfd_valid(self):
+ pnf_package_info = query_pnf_descriptor({"pnfId": self.pnfdInfoId})
+ if not pnf_package_info:
+ raise NSLCMException("Pnfd(%s) does not exist." % self.pnfdInfoId)
+
+ def build_cpInfo(self):
+ # todo
+ pass
+
+ def build_emsId(self):
+ # todo
+ pass
+
+ def create_pnf_inst(self):
+ pnfInstances = PNFInstModel.objects.filter(pnfId=self.pnfId)
+ if pnfInstances:
+ if not pnfInstances.filter(nsInstances__contains=self.nsInstances):
+ for pnfInstance in pnfInstances:
+ new_nsInstances = pnfInstance.nsInstances + "," + self.nsInstances
+ pnfInstance.update(nsInstances=new_nsInstances)
+ else:
+ PNFInstModel(pnfId=self.pnfId,
+ pnfName=self.pnfName,
+ pnfdId=self.pnfdId,
+ pnfdInfoId=self.pnfdInfoId,
+ pnfProfileId=self.pnfProfileId,
+ cpInfo=self.cpInfo,
+ emsId=self.emsId,
+ nsInstances=self.nsInstances).save()
diff --git a/lcm/ns_pnfs/biz/delete_pnf.py b/lcm/ns_pnfs/biz/delete_pnf.py
new file mode 100644
index 00000000..513fd97e
--- /dev/null
+++ b/lcm/ns_pnfs/biz/delete_pnf.py
@@ -0,0 +1,34 @@
+# Copyright 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.
+# 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 lcm.pub.database.models import PNFInstModel
+
+logger = logging.getLogger(__name__)
+
+
+class DeletePnf(object):
+ def __init__(self, pnf_id):
+ self.pnfId = pnf_id
+
+ def do_biz(self):
+ self.check_pnf_used()
+ self.delete_pnf()
+
+ def check_pnf_used(self):
+ pass # todo check whether the PNF is used in NS Instances
+
+ def delete_pnf(self):
+ logger.debug("delele PnfInstModel(%s)", self.pnfId)
+ PNFInstModel.objects.filter(pnfId=self.pnfId).delete()
diff --git a/lcm/ns_pnfs/biz/get_pnf.py b/lcm/ns_pnfs/biz/get_pnf.py
new file mode 100644
index 00000000..a01abad6
--- /dev/null
+++ b/lcm/ns_pnfs/biz/get_pnf.py
@@ -0,0 +1,33 @@
+# Copyright 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.
+# 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.
+
+from lcm.pub.database.models import PNFInstModel
+
+
+class GetPnf(object):
+ def __init__(self, filter=None, isIndividual=False):
+ self.filter = filter
+ self.isIndividual = isIndividual
+
+ def do_biz(self):
+ if self.filter and "pnfId" in self.filter:
+ pnf_instances = PNFInstModel.objects.filter(pnfId=self.filter["pnfId"])
+ if pnf_instances and self.isIndividual:
+ return pnf_instances[0]
+ else:
+ return pnf_instances
+ elif self.filter and "nsInstanceId" in self.filter:
+ return PNFInstModel.objects.filter(nsInstances__contains=self.filter["nsInstanceId"])
+ else:
+ return PNFInstModel.objects.all()
diff --git a/lcm/ns_pnfs/serializers/__init__.py b/lcm/ns_pnfs/serializers/__init__.py
new file mode 100644
index 00000000..342c2a8c
--- /dev/null
+++ b/lcm/ns_pnfs/serializers/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 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.
+# 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.
diff --git a/lcm/ns_pnfs/serializers/pnf_serializer.py b/lcm/ns_pnfs/serializers/pnf_serializer.py
new file mode 100644
index 00000000..b3d7410b
--- /dev/null
+++ b/lcm/ns_pnfs/serializers/pnf_serializer.py
@@ -0,0 +1,28 @@
+# Copyright 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.
+# 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.
+
+from rest_framework import serializers
+
+
+class PnfInstanceSerializer(serializers.Serializer):
+ pnfId = serializers.CharField(help_text="Identifier of the PNF.", required=True, allow_null=False)
+ pnfName = serializers.CharField(help_text="Name of the PNF.", required=True, allow_null=True)
+ pnfdId = serializers.CharField(help_text="Identifier of the PNFD on which the PNF is based.", required=True, allow_null=True)
+ pnfdInfoId = serializers.CharField(help_text="Identifier of the PNFD information object related to this PNF.", required=True, allow_null=True)
+ pnfProfileId = serializers.CharField(help_text="Identifier of the related PnfProfile in the NSD on which the PNF is based.", required=True, allow_null=True)
+ cpInfo = serializers.CharField(help_text="Information on the external CP of the PNF.", required=True, allow_null=True)
+
+
+class PnfInstancesSerializer(serializers.ListSerializer):
+ child = PnfInstanceSerializer()
diff --git a/lcm/ns_pnfs/tests/__init__.py b/lcm/ns_pnfs/tests/__init__.py
new file mode 100644
index 00000000..342c2a8c
--- /dev/null
+++ b/lcm/ns_pnfs/tests/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 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.
+# 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.
diff --git a/lcm/ns_pnfs/tests/test_create_pnf.py b/lcm/ns_pnfs/tests/test_create_pnf.py
new file mode 100644
index 00000000..c248ecb5
--- /dev/null
+++ b/lcm/ns_pnfs/tests/test_create_pnf.py
@@ -0,0 +1,90 @@
+# Copyright 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.
+# 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 uuid
+import mock
+import json
+from django.test import TestCase, Client
+from rest_framework import status
+from lcm.ns_pnfs.biz.create_pnf import CreatePnf
+from lcm.pub.utils import restcall
+
+
+class TestCreatePnfViews(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ def tearDown(self):
+ pass
+
+ @mock.patch.object(restcall, 'call_req')
+ def test_do_biz(self, mock_call_req):
+ mock_call_req.return_value = [0, json.JSONEncoder().encode({
+ 'id': str(uuid.uuid4()),
+ 'pnfdId': 'test',
+ 'pnfdName': 'test',
+ 'pnfdVersion': 'v1.1.0',
+ 'pnfdProvider': 'ZTE',
+ 'pnfdInvariantId': str(uuid.uuid4())
+ }), '200']
+ id = str(uuid.uuid4())
+ data = {
+ "pnfId": id,
+ "pnfName": "Test PNF",
+ "pnfdId": str(uuid.uuid4()),
+ "pnfdInfoId": str(uuid.uuid4()),
+ "pnfProfileId": str(uuid.uuid4()),
+ "cpInfo": [
+ {
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }
+ ],
+ "emsId": str(uuid.uuid4()),
+ "nsInstances": str(uuid.uuid4()) + "," + str(uuid.uuid4())
+ }
+ ret = CreatePnf(data).do_biz()
+ self.assertIsNotNone(ret)
+
+ @mock.patch.object(restcall, 'call_req')
+ def test_rest_api(self, mock_call_req):
+ mock_call_req.return_value = [0, json.JSONEncoder().encode({
+ 'id': str(uuid.uuid4()),
+ 'pnfdId': 'test',
+ 'pnfdName': 'test',
+ 'pnfdVersion': 'v1.1.0',
+ 'pnfdProvider': 'ZTE',
+ 'pnfdInvariantId': str(uuid.uuid4())
+ }), '200']
+ id = str(uuid.uuid4())
+ data = {
+ "pnfId": id,
+ "pnfName": "Test PNF",
+ "pnfdId": str(uuid.uuid4()),
+ "pnfdInfoId": str(uuid.uuid4()),
+ "pnfProfileId": str(uuid.uuid4()),
+ "cpInfo": [
+ {
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }
+ ],
+ "emsId": str(uuid.uuid4()),
+ "nsInstances": str(uuid.uuid4()) + "," + str(uuid.uuid4())
+ }
+
+ response = self.client.post("/api/nslcm/v1/pnfs", data=data, format='json')
+ self.assertEqual(status.HTTP_201_CREATED, response.status_code)
diff --git a/lcm/ns_pnfs/tests/test_delete_pnf.py b/lcm/ns_pnfs/tests/test_delete_pnf.py
new file mode 100644
index 00000000..1cf431e6
--- /dev/null
+++ b/lcm/ns_pnfs/tests/test_delete_pnf.py
@@ -0,0 +1,58 @@
+# Copyright 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.
+# 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 uuid
+from django.test import TestCase, Client
+from rest_framework import status
+from lcm.ns_pnfs.biz.delete_pnf import DeletePnf
+from lcm.pub.database.models import PNFInstModel
+
+
+class TestDeletePnfViews(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ def tearDown(self):
+ pass
+
+ def test_do_biz(self):
+ pnfId = str(uuid.uuid4())
+ PNFInstModel(pnfId=pnfId,
+ pnfName="Test PNF",
+ pnfdId=str(uuid.uuid4()),
+ pnfdInfoId=str(uuid.uuid4()),
+ pnfProfileId=str(uuid.uuid4()),
+ cpInfo=[{
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }]).save()
+ DeletePnf(pnfId).do_biz()
+ pnfInst = PNFInstModel.objects.filter(pnfId=pnfId)
+ self.assertEqual(0, len(pnfInst))
+
+ def test_rest_api(self):
+ pnfId = str(uuid.uuid4())
+ PNFInstModel(pnfId=pnfId,
+ pnfName="Test PNF",
+ pnfdId=str(uuid.uuid4()),
+ pnfdInfoId=str(uuid.uuid4()),
+ pnfProfileId=str(uuid.uuid4()),
+ cpInfo=[{
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }]).save()
+ response = self.client.delete("/api/nslcm/v1/pnfs/%s" % pnfId)
+ self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code)
diff --git a/lcm/ns_pnfs/tests/test_get_pnf.py b/lcm/ns_pnfs/tests/test_get_pnf.py
new file mode 100644
index 00000000..e5688733
--- /dev/null
+++ b/lcm/ns_pnfs/tests/test_get_pnf.py
@@ -0,0 +1,99 @@
+# Copyright 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.
+# 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 uuid
+from django.test import TestCase, Client
+from rest_framework import status
+from lcm.ns_pnfs.biz.get_pnf import GetPnf
+from lcm.pub.database.models import PNFInstModel
+
+
+class TestGetPnfViews(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ def tearDown(self):
+ pass
+
+ def test_pnfid_filter(self):
+ pnfId = str(uuid.uuid4())
+ PNFInstModel(pnfId=pnfId,
+ pnfName="Test PNF",
+ pnfdId=str(uuid.uuid4()),
+ pnfdInfoId=str(uuid.uuid4()),
+ pnfProfileId=str(uuid.uuid4()),
+ cpInfo=[{
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }]).save()
+ pnfInst = GetPnf({"pnfId": pnfId}).do_biz()
+ self.assertEqual("Test PNF", pnfInst[0].pnfName)
+
+ def test_nsInstanceid_filter(self):
+ pnfId = str(uuid.uuid4())
+ nsInstanceId = str(uuid.uuid4())
+ PNFInstModel(pnfId=pnfId,
+ pnfName="Test PNF",
+ pnfdId=str(uuid.uuid4()),
+ pnfdInfoId=str(uuid.uuid4()),
+ pnfProfileId=str(uuid.uuid4()),
+ cpInfo=[{
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }],
+ emsId=str(uuid.uuid4()),
+ nsInstances=nsInstanceId
+ ).save()
+ pnfInst = GetPnf({"nsInstanceId": nsInstanceId}).do_biz()
+ self.assertEqual("Test PNF", pnfInst[0].pnfName)
+
+ def test_get_instances_restapi(self):
+ pnfId = str(uuid.uuid4())
+ nsInstanceId = str(uuid.uuid4())
+ PNFInstModel(pnfId=pnfId,
+ pnfName="Test PNF",
+ pnfdId=str(uuid.uuid4()),
+ pnfdInfoId=str(uuid.uuid4()),
+ pnfProfileId=str(uuid.uuid4()),
+ cpInfo=[{
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }],
+ emsId=str(uuid.uuid4()),
+ nsInstances=nsInstanceId
+ ).save()
+ response = self.client.get("/api/nslcm/v1/pnfs")
+ self.assertEqual(status.HTTP_200_OK, response.status_code)
+
+ def test_get_individual_instance_restapi(self):
+ pnfId = str(uuid.uuid4())
+ nsInstanceId = str(uuid.uuid4())
+ PNFInstModel(pnfId=pnfId,
+ pnfName="Test PNF",
+ pnfdId=str(uuid.uuid4()),
+ pnfdInfoId=str(uuid.uuid4()),
+ pnfProfileId=str(uuid.uuid4()),
+ cpInfo=[{
+ "cpInstanceId": str(uuid.uuid4()),
+ "cpdId": "pnf_ext_cp01",
+ "cpProtocolData": []
+ }],
+ emsId=str(uuid.uuid4()),
+ nsInstances=nsInstanceId
+ ).save()
+ response = self.client.get("/api/nslcm/v1/pnfs/%s" % pnfId)
+ self.assertEqual(status.HTTP_200_OK, response.status_code)
diff --git a/lcm/ns_pnfs/urls.py b/lcm/ns_pnfs/urls.py
new file mode 100644
index 00000000..8237b640
--- /dev/null
+++ b/lcm/ns_pnfs/urls.py
@@ -0,0 +1,24 @@
+# Copyright 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.
+# 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.
+
+from django.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
+from lcm.ns_pnfs.views.pnf_view import PnfView, IndividualPnfView
+
+urlpatterns = [
+ url(r'^api/nslcm/v1/pnfs$', PnfView.as_view()),
+ url(r'^api/nslcm/v1/pnfs/(?P<pnf_id>[0-9a-zA-Z_-]+)$', IndividualPnfView.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/lcm/ns_pnfs/views/__init__.py b/lcm/ns_pnfs/views/__init__.py
new file mode 100644
index 00000000..342c2a8c
--- /dev/null
+++ b/lcm/ns_pnfs/views/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 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.
+# 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.
diff --git a/lcm/ns_pnfs/views/pnf_view.py b/lcm/ns_pnfs/views/pnf_view.py
new file mode 100644
index 00000000..0e1ae6fe
--- /dev/null
+++ b/lcm/ns_pnfs/views/pnf_view.py
@@ -0,0 +1,119 @@
+# Copyright 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.
+# 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 traceback
+
+from drf_yasg.utils import swagger_auto_schema
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.views import APIView
+from lcm.ns_pnfs.serializers.pnf_serializer import PnfInstanceSerializer, PnfInstancesSerializer
+from lcm.ns_pnfs.biz.create_pnf import CreatePnf
+from lcm.ns_pnfs.biz.delete_pnf import DeletePnf
+from lcm.ns_pnfs.biz.get_pnf import GetPnf
+from lcm.pub.exceptions import NSLCMException
+
+logger = logging.getLogger(__name__)
+
+
+class PnfView(APIView):
+ @swagger_auto_schema(
+ request_body=PnfInstanceSerializer(),
+ responses={
+ status.HTTP_201_CREATED: PnfInstanceSerializer()
+ }
+ )
+ def post(self, request):
+ logger.debug("PnfView--post::> %s" % request.data)
+
+ req_serializer = PnfInstanceSerializer(data=request.data)
+ if not req_serializer.is_valid():
+ logger.error(req_serializer.errors)
+ resp = {"result": 1, "detail": req_serializer.errors, "pnfId": ""}
+ return Response(data=resp, status=status.HTTP_201_CREATED)
+
+ pnfInstData = CreatePnf(request.data).do_biz()
+ resp_serializer = PnfInstanceSerializer(data=pnfInstData.__dict__)
+ if not resp_serializer.is_valid():
+ logger.error(resp_serializer.errors)
+ resp = {"result": 1, "detail": resp_serializer.errors, "pnfId": ""}
+ return Response(data=resp, status=status.HTTP_201_CREATED)
+
+ return Response(data=resp_serializer.data, status=status.HTTP_201_CREATED)
+
+ @swagger_auto_schema(
+ request_body="None",
+ responses={
+ status.HTTP_200_OK: PnfInstancesSerializer(help_text="Pnf instances", many=True),
+ status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
+ }
+ )
+ def get(self, request):
+ try:
+ logger.debug("PnfView::get")
+ pnfInstDataSet = GetPnf().do_biz()
+ logger.debug("PnfView::get::ret=%s", pnfInstDataSet)
+ resp_serializer = PnfInstancesSerializer(data=[pnfInstData.__dict__ for pnfInstData in pnfInstDataSet])
+ if not resp_serializer.is_valid():
+ raise NSLCMException(resp_serializer.errors)
+ return Response(data=resp_serializer.data, status=status.HTTP_200_OK)
+ except Exception as e:
+ logger.error(traceback.format_exc())
+ logger.error("Exception in GetPnf: %s", e.message)
+ return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+
+class IndividualPnfView(APIView):
+ @swagger_auto_schema(
+ request_body="None",
+ responses={
+ status.HTTP_204_NO_CONTENT: 'successful',
+ status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error"
+ }
+ )
+ def delete(self, request, pnf_id):
+ try:
+ logger.debug("Enter IndividualPnfView::delete pnf(%s)", pnf_id)
+ DeletePnf(pnf_id).do_biz()
+ return Response(data={}, status=status.HTTP_204_NO_CONTENT)
+ except Exception as e:
+ logger.error(traceback.format_exc())
+ logger.error("Exception in delete pnf: %s", e.message)
+ return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+ @swagger_auto_schema(
+ request_body="None",
+ responses={
+ status.HTTP_200_OK: PnfInstanceSerializer(help_text="Pnf instance", many=True),
+ status.HTTP_500_INTERNAL_SERVER_ERROR: "Inner error",
+ status.HTTP_404_NOT_FOUND: "Pnf instance does not exist"
+ }
+ )
+ def get(self, request, pnf_id):
+ try:
+ logger.debug("Enter IndividualPnfView::get pnf(%s)", pnf_id)
+ pnf_filter = {"pnfId": pnf_id}
+ pnfInstData = GetPnf(pnf_filter, True).do_biz()
+ if not pnfInstData:
+ return Response(status=status.HTTP_404_NOT_FOUND)
+ logger.debug("Leave IndividualPnfView::get::ret=%s", pnfInstData)
+ resp_serializer = PnfInstanceSerializer(data=pnfInstData.__dict__)
+ if not resp_serializer.is_valid():
+ raise NSLCMException(resp_serializer.errors)
+ return Response(data=resp_serializer.data, status=status.HTTP_200_OK)
+ except Exception as e:
+ logger.error(traceback.format_exc())
+ logger.error("Exception in IndividualPnfView: %s", e.message)
+ return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)