aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordyh <dengyuanhong@chinamobile.com>2019-03-21 11:39:41 +0800
committerdeng yuanhong <dengyuanhong@chinamobile.com>2019-03-22 06:21:47 +0000
commit363bc9d6d9f3803c6d80198865307c797d4809e2 (patch)
tree73f66918f67fc01dbc8968c9e651aa30ccad507b
parent3aed8eb825b0064d6e0c11091a751e29915a73d1 (diff)
Implement Service package management RESTAPIs
Change-Id: Iee7a3c94cb6091baddf7a44ef92b70e64f8045dd Issue-ID: VFC-1308 Signed-off-by: dyh <dengyuanhong@chinamobile.com>
-rw-r--r--catalog/packages/biz/sdc_service_package.py116
-rw-r--r--catalog/packages/biz/service_descriptor.py127
-rw-r--r--catalog/packages/serializers/catalog_serializers.py64
-rw-r--r--catalog/packages/tests/test_servicepackage.py143
-rwxr-xr-xcatalog/packages/urls.py2
-rw-r--r--catalog/packages/views/catalog_views.py117
-rw-r--r--catalog/packages/views/common.py4
-rw-r--r--catalog/pub/database/models.py23
-rw-r--r--catalog/pub/exceptions.py8
9 files changed, 603 insertions, 1 deletions
diff --git a/catalog/packages/biz/sdc_service_package.py b/catalog/packages/biz/sdc_service_package.py
new file mode 100644
index 00000000..bae1f71d
--- /dev/null
+++ b/catalog/packages/biz/sdc_service_package.py
@@ -0,0 +1,116 @@
+# Copyright (c) 2019, 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 traceback
+
+from coverage.xmlreport import os
+
+from catalog.packages.biz.service_descriptor import ServiceDescriptor
+from catalog.pub.config.config import CATALOG_ROOT_PATH, REG_TO_MSB_REG_PARAM, CATALOG_URL_PATH
+from catalog.pub.database.models import ServicePackageModel
+from catalog.pub.exceptions import CatalogException, PackageNotFoundException, \
+ PackageHasExistsException
+from catalog.pub.msapi import sdc
+from catalog.pub.utils import fileutil, toscaparser
+
+logger = logging.getLogger(__name__)
+
+
+class ServicePackage(object):
+ """
+ Actions for sdc service package.
+ """
+
+ def __init__(self):
+ pass
+
+ def on_distribute(self, csar_id):
+ if ServicePackageModel.objects.filter(servicePackageId=csar_id):
+ raise PackageHasExistsException("Service CSAR(%s) already exists." % csar_id)
+
+ try:
+ artifact = sdc.get_artifact(sdc.ASSETTYPE_SERVICES, csar_id)
+ local_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
+ csar_name = "%s.csar" % artifact.get("name", csar_id)
+ local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path, csar_name)
+ if local_file_name.endswith(".csar") or local_file_name.endswith(".zip"):
+ artifact_vnf_file = fileutil.unzip_file(local_file_name, local_path,
+ "Artifacts/Deployment/OTHER/ns.csar")
+ if os.path.exists(artifact_vnf_file):
+ local_file_name = artifact_vnf_file
+
+ data = {
+ 'userDefinedData': {}
+ }
+ serviced = ServiceDescriptor()
+ serviced.create(data, csar_id)
+ serviced.parse_serviced_and_save(csar_id, local_file_name)
+
+ except Exception as e:
+ logger.error(traceback.format_exc())
+ if ServicePackageModel.objects.filter(servicePackageId=csar_id):
+ ServicePackage().delete_csar(csar_id)
+ raise e
+
+ def delete_csar(self, csar_id):
+ serviced = ServiceDescriptor()
+ serviced.delete_single(csar_id)
+
+ def get_csars(self):
+ csars = []
+ packages = ServicePackageModel.objects.filter()
+ for package in packages:
+ csar = self.get_csar(package.servicePackageId)
+ csars.append(csar)
+ return csars
+
+ def get_csar(self, csar_id):
+ package_info = {}
+ csars = ServicePackageModel.objects.filter(servicePackageId=csar_id)
+ if csars:
+ package_info["servicedId"] = csars[0].servicedId
+ package_info["servicePackageId"] = csars[0].servicePackageId
+ package_info["servicedProvider"] = csars[0].servicedDesigner
+ package_info["servicedVersion"] = csars[0].servicedVersion
+ package_info["csarName"] = csars[0].servicePackageUri
+ package_info["servicedModel"] = csars[0].servicedModel
+ package_info["servicedInvariantId"] = csars[0].invariantId
+ package_info["downloadUrl"] = "http://%s:%s/%s/%s/%s" % (
+ REG_TO_MSB_REG_PARAM[0]["nodes"][0]["ip"],
+ REG_TO_MSB_REG_PARAM[0]["nodes"][0]["port"],
+ CATALOG_URL_PATH,
+ csar_id,
+ csars[0].servicePackageUri)
+ else:
+ raise PackageNotFoundException("Service package[%s] not Found." % csar_id)
+
+ return {"csarId": csar_id, "packageInfo": package_info}
+
+ def parse_serviced(csar_id, inputs):
+ service_pkg = ServicePackageModel.objects.filter(servicePackageId=csar_id)
+ if not service_pkg:
+ raise PackageNotFoundException("Service CSAR(%s) does not exist." % csar_id)
+
+ try:
+ csar_path = service_pkg[0].localFilePath
+ ret = {"model": toscaparser.parse_nsd(csar_path, inputs)}
+ return ret
+ except CatalogException as e:
+ logger.error(e.message)
+ raise e
+ except Exception as e:
+ logger.error(e.message)
+ logger.error(traceback.format_exc())
+ raise e
diff --git a/catalog/packages/biz/service_descriptor.py b/catalog/packages/biz/service_descriptor.py
new file mode 100644
index 00000000..72a561ae
--- /dev/null
+++ b/catalog/packages/biz/service_descriptor.py
@@ -0,0 +1,127 @@
+# Copyright (c) 2019, 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 json
+import logging
+import os
+import uuid
+
+from catalog.packages.const import PKG_STATUS
+from catalog.pub.config.config import CATALOG_ROOT_PATH
+from catalog.pub.database.models import ServicePackageModel
+from catalog.pub.exceptions import CatalogException, PackageNotFoundException
+from catalog.pub.utils import toscaparser, fileutil
+from catalog.pub.utils.values import ignore_case_get
+
+logger = logging.getLogger(__name__)
+
+
+class ServiceDescriptor(object):
+
+ def __init__(self):
+ pass
+
+ def create(self, data, csar_id):
+ logger.info('Start to create a ServiceD...')
+ user_defined_data = ignore_case_get(data, 'userDefinedData', {})
+ data = {
+ 'id': id if id else str(uuid.uuid4()),
+ 'servicedOnboardingState': PKG_STATUS.CREATED,
+ 'servicedOperationalState': PKG_STATUS.DISABLED,
+ 'servicedUsageState': PKG_STATUS.NOT_IN_USE,
+ 'userDefinedData': user_defined_data,
+ '_links': None # TODO
+ }
+ ServicePackageModel.objects.create(
+ servicePackageId=data['id'],
+ onboardingState=data['servicedOnboardingState'],
+ operationalState=data['servicedOperationalState'],
+ usageState=data['servicedUsageState'],
+ userDefinedData=json.dumps(user_defined_data)
+ )
+ logger.info('A ServiceD(%s) has been created.' % data['id'])
+ return data
+
+ def parse_serviced_and_save(self, serviced_info_id, local_file_name):
+ logger.info('Start to process ServiceD(%s)...' % serviced_info_id)
+ service_pkgs = ServicePackageModel.objects.filter(servicePackageId=serviced_info_id)
+ service_pkgs.update(onboardingState=PKG_STATUS.PROCESSING)
+
+ serviced_json = toscaparser.parse_nsd(local_file_name) # TODO
+ logger.debug("%s", serviced_json)
+ serviced = json.JSONDecoder().decode(serviced_json)
+
+ serviced_id = serviced.get("ns", {}).get("properties", {}).get("descriptor_id", "")
+ serviced_name = serviced.get("ns", {}).get("properties", {}).get("name", "")
+ serviced_version = serviced.get("ns", {}).get("properties", {}).get("version", "")
+ serviced_designer = serviced.get("ns", {}).get("properties", {}).get("designer", "")
+ invariant_id = serviced.get("ns", {}).get("properties", {}).get("invariant_id", "")
+ if serviced_id == "":
+ raise CatalogException("serviced_id(%s) does not exist in metadata." % serviced_id)
+ other_nspkg = ServicePackageModel.objects.filter(nsdId=serviced_id)
+ if other_nspkg and other_nspkg[0].servicePackageId != serviced_info_id:
+ logger.warn("ServiceD(%s,%s) already exists.", serviced_id, other_nspkg[0].servicePackageId)
+ raise CatalogException("ServiceD(%s) already exists." % serviced_id)
+
+ for vnf in serviced["vnfs"]:
+ vnfd_id = vnf["properties"].get("descriptor_id", "undefined")
+ if vnfd_id == "undefined":
+ vnfd_id = vnf["properties"].get("id", "undefined")
+ pkg = ServicePackageModel.objects.filter(vnfdId=vnfd_id)
+ if not pkg:
+ pkg = ServicePackageModel.objects.filter(vnfPackageId=vnfd_id)
+ if not pkg:
+ vnfd_name = vnf.get("vnf_id", "undefined")
+ logger.error("[%s] is not distributed.", vnfd_name)
+ raise CatalogException("VNF package(%s) is not distributed." % vnfd_id)
+
+ for pnf in serviced["pnfs"]:
+ pnfd_id = pnf["properties"].get("descriptor_id", "undefined")
+ if pnfd_id == "undefined":
+ pnfd_id = pnf["properties"].get("id", "undefined")
+ pkg = ServicePackageModel.objects.filter(pnfdId=pnfd_id)
+ if not pkg:
+ pkg = ServicePackageModel.objects.filter(pnfPackageId=pnfd_id)
+ if not pkg:
+ pnfd_name = pnf.get("pnf_id", "undefined")
+ logger.error("[%s] is not distributed.", pnfd_name)
+ raise CatalogException("PNF package(%s) is not distributed." % pnfd_name)
+
+ service_pkgs.update(
+ servicedId=serviced_id,
+ servicedName=serviced_name,
+ servicedDesginer=serviced_designer,
+ servicedDescription=serviced.get("description", ""),
+ servicedVersion=serviced_version,
+ invariantId=invariant_id,
+ onboardingState=PKG_STATUS.ONBOARDED,
+ operationalState=PKG_STATUS.ENABLED,
+ usageState=PKG_STATUS.NOT_IN_USE,
+ servicePackageUri=local_file_name,
+ sdcCsarId=serviced_info_id,
+ localFilePath=local_file_name,
+ servicedModel=serviced_json
+ )
+ logger.info('ServiceD(%s) has been processed.' % serviced_info_id)
+
+ def delete_single(self, serviced_info_id):
+ logger.info('Start to delete ServiceD(%s)...' % serviced_info_id)
+ service_pkgs = ServicePackageModel.objects.filter(servicePackageId=serviced_info_id)
+ if not service_pkgs.exists():
+ logger.warn('ServiceD(%s) not found.' % serviced_info_id)
+ raise PackageNotFoundException("Service package[%s] not Found." % serviced_info_id)
+ service_pkgs.delete()
+ service_pkg_path = os.path.join(CATALOG_ROOT_PATH, serviced_info_id)
+ fileutil.delete_dirs(service_pkg_path)
+ logger.info('ServiceD(%s) has been deleted.' % serviced_info_id)
diff --git a/catalog/packages/serializers/catalog_serializers.py b/catalog/packages/serializers/catalog_serializers.py
index 90006c92..0e830e5e 100644
--- a/catalog/packages/serializers/catalog_serializers.py
+++ b/catalog/packages/serializers/catalog_serializers.py
@@ -132,6 +132,70 @@ class NsPackagesSerializer(serializers.ListSerializer):
child = NsPackageSerializer()
+class ServicePackageDistributeRequestSerializer(serializers.Serializer):
+ csarId = serializers.CharField(help_text="csarId", required=True)
+
+
+class ServicePackageInfoSerializer(serializers.Serializer):
+ servicedId = serializers.CharField(
+ help_text="ServiceD ID",
+ required=False,
+ allow_null=True
+ )
+ servicePackageId = serializers.CharField(
+ help_text="Service Package ID",
+ allow_blank=True,
+ required=False,
+ allow_null=True
+ )
+ servicedProvider = serializers.CharField(
+ help_text="ServiceD Provider",
+ allow_blank=True,
+ required=False,
+ allow_null=True
+ )
+ servicedVersion = serializers.CharField(
+ help_text="ServiceD Version",
+ allow_blank=True,
+ required=False,
+ allow_null=True
+ )
+ csarName = serializers.CharField(
+ help_text="CSAR name",
+ allow_blank=True,
+ required=False,
+ allow_null=True
+ )
+ servicedModel = serializers.CharField(
+ help_text="ServiceD Model",
+ allow_blank=True,
+ required=False,
+ allow_null=True
+ )
+ downloadUrl = serializers.CharField(
+ help_text="URL to download ServiceD Model",
+ required=False,
+ allow_null=True
+ )
+
+
+class ServicePackageSerializer(serializers.Serializer):
+ csarId = serializers.CharField(
+ help_text="CSAR ID",
+ required=False,
+ allow_null=True
+ )
+ packageInfo = ServicePackageInfoSerializer(
+ help_text="Service Package Info",
+ required=False,
+ allow_null=True
+ )
+
+
+class ServicePackagesSerializer(serializers.ListSerializer):
+ child = ServicePackageSerializer()
+
+
class NfPackageDistributeRequestSerializer(serializers.Serializer):
csarId = serializers.CharField(help_text="CSAR ID", required=True)
vimIds = serializers.ListField(
diff --git a/catalog/packages/tests/test_servicepackage.py b/catalog/packages/tests/test_servicepackage.py
new file mode 100644
index 00000000..86d513e0
--- /dev/null
+++ b/catalog/packages/tests/test_servicepackage.py
@@ -0,0 +1,143 @@
+# Copyright (c) 2019, 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.
+
+from django.test import TestCase, Client
+from rest_framework import status
+
+from catalog.packages.biz.sdc_service_package import ServicePackage
+from catalog.pub.database.models import ServicePackageModel
+from catalog.pub.exceptions import PackageNotFoundException, PackageHasExistsException
+
+
+class TestServicePackage(TestCase):
+ """ Test case for Service Package operations"""
+
+ def setUp(self):
+ self.client = Client()
+ ServicePackageModel.objects.filter().delete()
+
+ def tearDown(self):
+ pass
+
+ ###############################################################
+
+ def test_service_pkg_distribute_when_pkg_exists(self):
+ ServicePackageModel(servicePackageId="1", servicedId="2").save()
+ csar_id = 1
+ try:
+ ServicePackage().on_distribute(csar_id)
+ except PackageHasExistsException as e:
+ self.assertEqual("Service CSAR(1) already exists.", e.message)
+
+ def test_api_service_pkg_distribute_when_pkg_exists(self):
+ ServicePackageModel(servicePackageId="1", servicedId="2").save()
+ resp = self.client.post(
+ "/api/parser/v1/service_packages", {"csarId": "1"}, format='json')
+ self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
+ self.assertEqual("Service CSAR(1) already exists.", resp.data["errorMessage"])
+
+ ###############################################################
+ def test_service_pkg_get_all(self):
+ ServicePackageModel(
+ servicePackageId="13",
+ servicedId="2",
+ servicedDesigner="2",
+ servicedVersion="2",
+ servicePackageUri="13.csar",
+ servicedModel="").save()
+ ServicePackageModel(
+ servicePackageId="14",
+ servicedId="3",
+ servicedDesigner="3",
+ servicedVersion="3",
+ servicePackageUri="14.csar",
+ servicedModel="").save()
+ csars = ServicePackage().get_csars()
+ self.assertEqual(2, len(csars))
+
+ def test_api_service_pkg_get_all(self):
+ ServicePackageModel(
+ servicePackageId="13",
+ servicedId="2",
+ servicedDesigner="2",
+ servicedVersion="2",
+ servicePackageUri="13.csar",
+ servicedModel="").save()
+ ServicePackageModel(
+ servicePackageId="14",
+ servicedId="3",
+ servicedDesigner="3",
+ servicedVersion="3",
+ servicePackageUri="14.csar",
+ servicedModel="").save()
+ resp = self.client.get("/api/parser/v1/service_packages")
+ self.assertEqual(resp.status_code, status.HTTP_200_OK)
+
+ ###############################################################
+
+ def test_service_pkg_get_one(self):
+ ServicePackageModel(
+ servicePackageId="14",
+ servicedId="2",
+ servicedDesigner="3",
+ servicedVersion="4",
+ servicePackageUri="14.csar",
+ servicedModel="").save()
+ csar = ServicePackage().get_csar(14)
+ self.assertEqual(14, csar['csarId'])
+
+ def test_service_pkg_get_one_not_found(self):
+ try:
+ ServicePackage().get_csar(1000)
+ except PackageNotFoundException as e:
+ self.assertEqual("Service package[1000] not Found.", e.message)
+
+ def test_api_service_pkg_get_one(self):
+ ServicePackageModel(
+ servicePackageId="14",
+ servicedId="2",
+ servicedDesigner="3",
+ servicedVersion="4",
+ servicePackageUri="14.csar",
+ servicedModel="").save()
+ resp = self.client.get("/api/parser/v1/service_packages/14")
+ self.assertEqual(resp.status_code, status.HTTP_200_OK)
+
+ def test_api_service_pkg_get_one_not_found(self):
+ resp = self.client.get("/api/parser/v1/service_packages/22")
+ self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND)
+ self.assertEqual(
+ {"errorMessage": "Service package[22] not Found.", 'error': 404},
+ resp.data)
+
+ ###############################################################
+
+ def test_service_pkg_normal_delete(self):
+ ServicePackageModel(servicePackageId="8", servicedId="2").save()
+ sp = ServicePackageModel.objects.filter(servicePackageId=8)
+ self.assertEqual(1, len(sp))
+ ServicePackage().delete_csar("8")
+ sp = ServicePackageModel.objects.filter(servicePackageId=8)
+ self.assertEqual(0, len(sp))
+
+ def test_service_pkg_normal_delete_not_found(self):
+ try:
+ ServicePackage().delete_csar("8000")
+ except PackageNotFoundException as e:
+ self.assertEqual("Service package[8000] not Found.", e.message)
+
+ def test_api_service_pkg_normal_delete(self):
+ ServicePackageModel(servicePackageId="8", servicedId="2").save()
+ resp = self.client.delete("/api/parser/v1/service_packages/8")
+ self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT)
diff --git a/catalog/packages/urls.py b/catalog/packages/urls.py
index dfd13261..3a3426e5 100755
--- a/catalog/packages/urls.py
+++ b/catalog/packages/urls.py
@@ -27,6 +27,8 @@ urlpatterns = [
url(r'^api/catalog/v1/nspackages/(?P<csarId>[0-9a-zA-Z\-\_]+)$', catalog_views.ns_rd_csar, name='nspackage_rd'),
url(r'^api/catalog/v1/vnfpackages$', catalog_views.nfpackages_rc, name='nfpackages_rc'),
url(r'^api/catalog/v1/vnfpackages/(?P<csarId>[0-9a-zA-Z\-\_]+)$', catalog_views.nf_rd_csar, name='nfpackage_rd'),
+ url(r'^api/parser/v1/service_packages$', catalog_views.servicepackages_rc, name='servicepackages_rc'),
+ url(r'^api/parser/v1/service_packages/(?P<csarId>[0-9a-zA-Z\-\_]+)$', catalog_views.service_rd_csar, name='servicepackage_rd'),
# NFV Model Parser
url(r'^api/catalog/v1/parsernsd$', catalog_views.ns_model_parser, name='nsmodelparser_rc'),
diff --git a/catalog/packages/views/catalog_views.py b/catalog/packages/views/catalog_views.py
index fd7f5d43..5496c6e0 100644
--- a/catalog/packages/views/catalog_views.py
+++ b/catalog/packages/views/catalog_views.py
@@ -21,7 +21,9 @@ from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from catalog.packages.biz import sdc_vnf_package, sdc_ns_package
-from catalog.packages.serializers.catalog_serializers import InternalErrorRequestSerializer
+from catalog.packages.biz.sdc_service_package import ServicePackage
+from catalog.packages.serializers.catalog_serializers import InternalErrorRequestSerializer, \
+ ServicePackageDistributeRequestSerializer, ServicePackagesSerializer, ServicePackageSerializer
from catalog.packages.serializers.catalog_serializers import NfPackageDistributeRequestSerializer
from catalog.packages.serializers.catalog_serializers import NfPackageSerializer
from catalog.packages.serializers.catalog_serializers import NfPackagesSerializer
@@ -32,6 +34,8 @@ from catalog.packages.serializers.catalog_serializers import NsPackagesSerialize
from catalog.packages.serializers.catalog_serializers import ParseModelRequestSerializer
from catalog.packages.serializers.catalog_serializers import ParseModelResponseSerializer
from catalog.packages.serializers.catalog_serializers import PostJobResponseSerializer
+from catalog.packages.views.common import fmt_error_rsp
+from catalog.pub.exceptions import PackageNotFoundException, PackageHasExistsException
from catalog.pub.utils.syscomm import fun_name
from catalog.pub.utils.values import ignore_case_get
@@ -209,6 +213,117 @@ def ns_rd_csar(request, *args, **kwargs):
@swagger_auto_schema(
+ method='POST',
+ operation_description="On distribute Service package",
+ request_body=ServicePackageDistributeRequestSerializer,
+ responses={
+ status.HTTP_202_ACCEPTED: "",
+ status.HTTP_400_BAD_REQUEST: InternalErrorRequestSerializer,
+ status.HTTP_500_INTERNAL_SERVER_ERROR: InternalErrorRequestSerializer})
+@swagger_auto_schema(
+ method='GET',
+ operation_description="Query Service packages",
+ request_body=no_body,
+ responses={
+ status.HTTP_200_OK: ServicePackagesSerializer,
+ status.HTTP_500_INTERNAL_SERVER_ERROR: InternalErrorRequestSerializer})
+@api_view(http_method_names=['POST', 'GET'])
+def servicepackages_rc(request, *args, **kwargs):
+ logger.debug("Enter %s, method is %s", fun_name(), request.method)
+
+ if request.method == 'GET':
+ # Gets service package list
+ try:
+ csar_list = ServicePackage().get_csars()
+ response_serializer = ServicePackagesSerializer(data=csar_list)
+ validation_error = handleValidatonError(response_serializer, False)
+ if validation_error:
+ return validation_error
+ return Response(data=csar_list, status=status.HTTP_200_OK)
+ except Exception as e:
+ error_status = status.HTTP_500_INTERNAL_SERVER_ERROR
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+ elif request.method == 'POST':
+ # Distributes the package according to the given csarId
+ request_serializer = ServicePackageDistributeRequestSerializer(data=request.data)
+ validation_error = handleValidatonError(request_serializer, True)
+ if validation_error:
+ return validation_error
+
+ csar_id = ignore_case_get(request.data, "csarId")
+ logger.debug("csar_id is %s", csar_id)
+ try:
+ ServicePackage().on_distribute(csar_id)
+ return Response(status=status.HTTP_202_ACCEPTED)
+ except PackageHasExistsException as e:
+ error_status = status.HTTP_400_BAD_REQUEST
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+ except Exception as e:
+ error_status = status.HTTP_500_INTERNAL_SERVER_ERROR
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+
+
+@swagger_auto_schema(
+ method='DELETE',
+ operation_description="Delete one Service package",
+ request_body=no_body,
+ manual_parameters=[
+ openapi.Parameter(
+ 'csarId',
+ openapi.IN_QUERY,
+ "csarId",
+ type=openapi.TYPE_STRING)],
+ responses={
+ status.HTTP_204_NO_CONTENT: "",
+ status.HTTP_404_NOT_FOUND: InternalErrorRequestSerializer,
+ status.HTTP_500_INTERNAL_SERVER_ERROR: InternalErrorRequestSerializer})
+@swagger_auto_schema(
+ method='GET',
+ operation_description="Query one Service package",
+ request_body=no_body,
+ manual_parameters=[
+ openapi.Parameter(
+ 'csarId',
+ openapi.IN_QUERY,
+ "csarId",
+ type=openapi.TYPE_STRING)],
+ responses={
+ status.HTTP_200_OK: ServicePackageSerializer,
+ status.HTTP_404_NOT_FOUND: InternalErrorRequestSerializer,
+ status.HTTP_500_INTERNAL_SERVER_ERROR: InternalErrorRequestSerializer})
+@api_view(http_method_names=['DELETE', 'GET'])
+def service_rd_csar(request, *args, **kwargs):
+ csar_id = ignore_case_get(kwargs, "csarId")
+ logger.info("Enter %s, method is %s, csar_id is %s", fun_name(), request.method, csar_id)
+
+ if request.method == 'GET':
+ try:
+ ret = ServicePackage().get_csar(csar_id)
+ response_serializer = ServicePackageSerializer(data=ret)
+ validation_error = handleValidatonError(response_serializer, False)
+ if validation_error:
+ return validation_error
+ return Response(data=ret, status=status.HTTP_200_OK)
+ except PackageNotFoundException as e:
+ error_status = status.HTTP_404_NOT_FOUND
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+ except Exception as e:
+ error_status = status.HTTP_500_INTERNAL_SERVER_ERROR
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+
+ elif request.method == 'DELETE':
+ try:
+ ServicePackage().delete_csar(csar_id)
+ return Response(status=status.HTTP_204_NO_CONTENT)
+ except PackageNotFoundException as e:
+ error_status = status.HTTP_404_NOT_FOUND
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+ except Exception as e:
+ error_status = status.HTTP_500_INTERNAL_SERVER_ERROR
+ return Response(data=fmt_error_rsp(e.message, error_status), status=error_status)
+
+
+@swagger_auto_schema(
method='DELETE',
operation_description="Delete one Nf package",
request_body=no_body,
diff --git a/catalog/packages/views/common.py b/catalog/packages/views/common.py
index 5dacb771..94566ebc 100644
--- a/catalog/packages/views/common.py
+++ b/catalog/packages/views/common.py
@@ -25,3 +25,7 @@ def validate_data(data, serializer):
logger.error('Data validation failed.')
raise CatalogException(serialized_data.errors)
return serialized_data
+
+
+def fmt_error_rsp(error_message, status):
+ return {"errorMessage": error_message, "error": status}
diff --git a/catalog/pub/database/models.py b/catalog/pub/database/models.py
index ef95dea9..9f0b4985 100644
--- a/catalog/pub/database/models.py
+++ b/catalog/pub/database/models.py
@@ -38,6 +38,29 @@ class NSPackageModel(models.Model):
db_table = 'CATALOG_NSPACKAGE'
+class ServicePackageModel(models.Model):
+ servicePackageId = models.CharField(db_column='SERVICEPACKAGEID', primary_key=True, max_length=50)
+ servicePackageUri = models.CharField(db_column='SERVICEPACKAGEURI', max_length=300, null=True, blank=True)
+ checksum = models.CharField(db_column='CHECKSUM', max_length=50, null=True, blank=True) # checksum
+ sdcCsarId = models.CharField(db_column='SDCCSARID', max_length=50, null=True, blank=True) # SdcCSARUri
+ onboardingState = models.CharField(db_column='ONBOARDINGSTATE', max_length=20, blank=True, null=True)
+ operationalState = models.CharField(db_column='OPERATIONALSTATE', max_length=20, blank=True, null=True) # operationalState
+ usageState = models.CharField(db_column='USAGESTATE', max_length=20, blank=True, null=True) # usageState
+ deletionPending = models.CharField(db_column='DELETIONPENDING', max_length=20, blank=True, null=True) # deletionPending
+ servicedId = models.CharField(db_column='SERVICEDID', max_length=50, blank=True, null=True)
+ invariantId = models.CharField(db_column='INVARIANTID', max_length=50, blank=True, null=True) # servicedInvariantId
+ servicedName = models.CharField(db_column='SERVICEDNAME', max_length=50, blank=True, null=True)
+ servicedDesigner = models.CharField(db_column='SERVICEDDESIGNER', max_length=50, null=True, blank=True)
+ servicedDescription = models.CharField(db_column='SERVICEDDESCRIPTION', max_length=100, null=True, blank=True)
+ servicedVersion = models.CharField(db_column='SERVICEDVERSION', max_length=20, null=True, blank=True)
+ userDefinedData = models.TextField(db_column='USERDEFINEDDATA', max_length=1024, blank=True, null=True) # userDefinedData
+ localFilePath = models.CharField(db_column='LOCALFILEPATH', max_length=300, null=True, blank=True)
+ servicedModel = models.TextField(db_column='SERVICEDMODEL', max_length=65535, null=True, blank=True)
+
+ class Meta:
+ db_table = 'CATALOG_SERVICEPACKAGE'
+
+
class VnfPackageModel(models.Model):
# uuid = models.CharField(db_column='UUID', primary_key=True, max_length=255)
vnfPackageId = models.CharField(db_column='VNFPACKAGEID', primary_key=True, max_length=50) # onboardedVnfPkgInfoId
diff --git a/catalog/pub/exceptions.py b/catalog/pub/exceptions.py
index afe45d16..a9354204 100644
--- a/catalog/pub/exceptions.py
+++ b/catalog/pub/exceptions.py
@@ -21,6 +21,14 @@ class ResourceNotFoundException(CatalogException):
pass
+class PackageNotFoundException(CatalogException):
+ pass
+
+
+class PackageHasExistsException(CatalogException):
+ pass
+
+
class VnfPkgSubscriptionException(CatalogException):
pass