Add a subscription api on gvnfmdriver.
[vfc/nfvo/driver/vnfm/gvnfm.git] / gvnfmadapter / driver / interfaces / views.py
index 7c56408..1cf6fa2 100644 (file)
@@ -23,32 +23,41 @@ from rest_framework import status
 from rest_framework.response import Response
 from rest_framework.views import APIView
 
+from driver.interfaces.serializers.serializers import VnfInstReqParamsSerializer, ResponseSerializer
+from driver.interfaces.serializers.serializers import VnfNotifyReqSerializer, VNFLCMOpOccSerializer
+from driver.interfaces.serializers.serializers import VnfOperRespSerializer
+from driver.interfaces.serializers.serializers import VnfTermReqSerializer, VnfQueryRespSerializer
+from driver.interfaces.serializers.grant_request import GrantRequestSerializer
+from driver.interfaces.serializers.grant import GrantSerializer
+from driver.interfaces.serializers.lccn_subscription import LccnSubscriptionSerializer
+from driver.interfaces.serializers.lccn_subscription_request import LccnSubscriptionRequestSerializer
 from driver.pub.exceptions import GvnfmDriverException
 from driver.pub.utils import restcall
 from driver.pub.utils.restcall import req_by_msb
-from driver.interfaces.serializers import VnfRequestParamsSerializer, ResponseSerializer, ErrorSerializer
 
 logger = logging.getLogger(__name__)
 
 
 class VnfInstInfo(APIView):
     @swagger_auto_schema(
-        request_body=VnfRequestParamsSerializer(),
+        request_body=VnfInstReqParamsSerializer(),
         responses={
             status.HTTP_201_CREATED: ResponseSerializer(),
-            status.HTTP_500_INTERNAL_SERVER_ERROR: ErrorSerializer()
+            status.HTTP_404_NOT_FOUND: "The vnfm instance id is wrong",
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
         }
     )
     def post(self, request, vnfmtype, vnfmid):
         logger.debug("instantiate_vnf--post::> %s" % request.data)
         logger.debug("Create vnf begin!")
         try:
-            requestSerializer = VnfRequestParamsSerializer(data=request.data)
+            requestSerializer = VnfInstReqParamsSerializer(data=request.data)
             request_isValid = requestSerializer.is_valid()
             if not request_isValid:
                 raise Exception(requestSerializer.errors)
 
-            requestData = requestSerializer.data
+            # requestData = requestSerializer.data
+            requestData = request.data
             input_data = {
                 "vnfdId": ignorcase_get(requestData, "vnfDescriptorId"),
                 "vnfInstanceName": ignorcase_get(requestData, "vnfInstanceName"),
@@ -62,11 +71,11 @@ class VnfInstInfo(APIView):
             logger.debug("Create vnf end!")
 
             logger.debug("Instantiate vnf start!")
-            vnfInstanceId = resp["vnfInstanceId"]
+            vnfInstanceId = resp["id"]
             input_data = {
                 "flavourId": ignorcase_get(requestData, "flavourId"),
                 "extVirtualLinks": ignorcase_get(requestData, "extVirtualLink"),
-                "additionalParams": ignorcase_get(requestData, "additionalParam")
+                "additionalParams": ignorcase_get(requestData, "additionalParam"),
             }
             logger.debug("do_instvnf: vnfInstanceId=[%s],request data=[%s],input_data=[%s],vnfm_id=[%s]",
                          vnfInstanceId, request.data, input_data, vnfm_id)
@@ -74,7 +83,7 @@ class VnfInstInfo(APIView):
             logger.debug("do_instvnf: response data=[%s]", resp)
             resp_data = {
                 "vnfInstanceId": vnfInstanceId,
-                "jobId": ignorcase_get(resp, "vnfLcOpId")
+                "jobId": ignorcase_get(resp, "jobId")
             }
             logger.debug("Instantiate vnf end!")
             return Response(data=resp_data, status=status.HTTP_201_CREATED)
@@ -87,11 +96,18 @@ class VnfInstInfo(APIView):
 
 
 class VnfTermInfo(APIView):
+    @swagger_auto_schema(
+        request_body=VnfTermReqSerializer(),
+        responses={
+            status.HTTP_201_CREATED: ResponseSerializer(),
+            status.HTTP_404_NOT_FOUND: "The vnfmid and vnfInstanceId are wrong",
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
+        }
+    )
     def post(self, request, vnfmtype, vnfmid, vnfInstanceId):
         logger.debug("terminate_vnf--post::> %s" % request.data)
         logger.debug("Terminate vnf begin!")
         vnfm_id = vnfmid
-        vnfInstanceId = vnfInstanceId
         try:
             input_data = {
                 "terminationType": ignorcase_get(request.data, "terminationType"),
@@ -102,7 +118,7 @@ class VnfTermInfo(APIView):
             resp = do_terminatevnf(vnfm_id, vnfInstanceId, input_data)
             logger.debug("terminate_vnf: response data=[%s]", resp)
 
-            jobId = ignorcase_get(resp, "vnfLcOpId")
+            jobId = ignorcase_get(resp, "jobId")
             gracefulTerminationTimeout = ignorcase_get(request.data, "gracefulTerminationTimeout")
             logger.debug("wait4job: vnfm_id=[%s],jobId=[%s],gracefulTerminationTimeout=[%s]",
                          vnfm_id, jobId, gracefulTerminationTimeout)
@@ -126,10 +142,16 @@ class VnfTermInfo(APIView):
 
 
 class VnfQueryInfo(APIView):
+    @swagger_auto_schema(
+        responses={
+            status.HTTP_201_CREATED: VnfQueryRespSerializer(),
+            status.HTTP_404_NOT_FOUND: "The vnfmid and vnfInstanceId are wrong",
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
+        }
+    )
     def get(self, request, vnfmtype, vnfmid, vnfInstanceId):
         logger.debug("query_vnf--post::> %s" % request.data)
         vnfm_id = vnfmid
-        vnfInstanceId = vnfInstanceId
         try:
             logger.debug("[%s] request.data=%s", fun_name(), request.data)
             resp = do_queryvnf(request, vnfm_id, vnfInstanceId)
@@ -144,15 +166,22 @@ class VnfQueryInfo(APIView):
                 "vnfType": "",
                 "vnfStatus": ""
             }
-            resp_response_data = mapping_conv(query_vnf_resp_mapping, ignorcase_get(resp, "ResponseInfo"))
+            ResponseInfo = ignorcase_get(resp, "ResponseInfo")
+            resp_response_data = mapping_conv(query_vnf_resp_mapping, ResponseInfo)
             resp_data = {
                 "vnfInfo": resp_response_data
             }
-            ResponseInfo = ignorcase_get(resp, "ResponseInfo")
-            resp_data["vnfInfo"]["version"] = ignorcase_get(ResponseInfo, "vnfSoftwareVersion")
+            id = ignorcase_get(ResponseInfo, "id")
+            if id:
+                resp_data["vnfInfo"]["vnfInstanceId"] = id
+            vnfPkgId = ignorcase_get(ResponseInfo, "vnfPkgId")
+            if vnfPkgId:
+                resp_data["vnfInfo"]["vnfPackageId"] = vnfPkgId
+            vnfSoftwareVersion = ignorcase_get(ResponseInfo, "vnfSoftwareVersion")
+            if vnfSoftwareVersion:
+                resp_data["vnfInfo"]["version"] = vnfSoftwareVersion
             if ignorcase_get(ResponseInfo, "instantiationState") == "INSTANTIATED":
                 resp_data["vnfInfo"]["vnfStatus"] = "ACTIVE"
-            resp_data["vnfInfo"]["vnfInstanceId"] = ignorcase_get(ResponseInfo, "vnfInstanceId")
             logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
             return Response(data=resp_data, status=status.HTTP_200_OK)
         except GvnfmDriverException as e:
@@ -164,6 +193,13 @@ class VnfQueryInfo(APIView):
 
 
 class VnfOperInfo(APIView):
+    @swagger_auto_schema(
+        responses={
+            status.HTTP_201_CREATED: VnfOperRespSerializer(),
+            status.HTTP_404_NOT_FOUND: "The vnfmid, jobid and responseId are wrong",
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
+        }
+    )
     def get(self, request, vnfmtype, vnfmid, jobid):
         logger.debug("operation_status--post::> %s" % request.data)
         try:
@@ -200,23 +236,31 @@ class VnfOperInfo(APIView):
 
 
 class VnfGrantInfo(APIView):
+    @swagger_auto_schema(
+        request_body=GrantRequestSerializer(),  # TODO: not used
+        responses={
+            status.HTTP_201_CREATED: GrantSerializer(),
+            status.HTTP_404_NOT_FOUND: "The request body is wrong",
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
+        }
+    )
     def put(self, request, vnfmtype):
         try:
             logger.debug("[grantvnf] req_data = %s", request.data)
-            ret = req_by_msb('api/nslcm/v1/grantvnf', "POST", content=json.JSONEncoder().encode(request.data))
+            grant_request = GrantRequestSerializer(data=request.data)
+            if not grant_request.is_valid():
+                raise GvnfmDriverException(grant_request.error_messages)
+            ret = req_by_msb('api/nslcm/v2/grants', "POST", content=json.JSONEncoder().encode(request.data))
             logger.debug("ret = %s", ret)
             if ret[0] != 0:
                 logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
                 raise GvnfmDriverException('Failed to grant vnf.')
             resp = json.JSONDecoder().decode(ret[1])
-            vim_info = resp['vim']
-            accessinfo = ignorcase_get(resp['vim'], 'accessinfo')
-            resp_data = {
-                'vimid': ignorcase_get(vim_info, 'vimid'),
-                'tenant': ignorcase_get(accessinfo, 'tenant')
-            }
-            logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
-            return Response(data=resp_data, status=status.HTTP_201_CREATED)
+            grant = GrantSerializer(data=resp)
+            if not grant.is_valid():
+                raise GvnfmDriverException(grant.error_messages)
+            logger.debug("[%s]resp_data=%s", fun_name(), resp)
+            return Response(data=resp, status=status.HTTP_201_CREATED)
         except GvnfmDriverException as e:
             logger.error('Grant vnf failed, detail message: %s' % e.message)
             return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@@ -226,11 +270,21 @@ class VnfGrantInfo(APIView):
 
 
 class VnfNotifyInfo(APIView):
-    def post(self, request, vnfmtype):
+    @swagger_auto_schema(
+        request_body=VnfNotifyReqSerializer(),
+        responses={
+            status.HTTP_201_CREATED: "Successful Notify",
+            status.HTTP_404_NOT_FOUND: "The request body is wrong",
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "The url is invalid"
+        }
+    )
+    def post(self, request, vnfmtype):  # TODO: not compatable with VnfIdentifierCreationNotification and VnfIdentifierDeletionNotification
         try:
             logger.debug("[%s]req_data = %s", fun_name(), request.data)
-            vnfinstanceid = ignorcase_get(request.data, 'vnfinstanceid')
-            ret = req_by_msb("api/nslcm/v1/vnfs/%s/Notify" % vnfinstanceid, "POST",
+            vnfminstid = ignorcase_get(request.data, 'vnfmInstId')
+            vnfinstanceid = ignorcase_get(request.data, 'vnfInstanceId')
+            request.data.pop("vnfmInstId")
+            ret = req_by_msb("api/nslcm/v2/ns/%s/vnfs/%s/Notify" % (vnfminstid, vnfinstanceid), "POST",
                              json.JSONEncoder().encode(request.data))
             logger.debug("[%s]data = %s", fun_name(), ret)
             if ret[0] != 0:
@@ -262,6 +316,68 @@ class VnfPkgsInfo(APIView):
             logger.error(traceback.format_exc())
             return Response(data={'error': 'unexpected exception'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
 
+class QuerySingleVnfLcmOpOcc(APIView):
+    @swagger_auto_schema(
+        responses={
+            status.HTTP_200_OK: VNFLCMOpOccSerializer(),
+            status.HTTP_500_INTERNAL_SERVER_ERROR: ""
+        }
+    )
+    def get(self, request, vnfmtype, vnfmid, lcmopoccid):
+        logger.debug("[%s]LCMOpOccId = %s", fun_name(), lcmopoccid)
+        try:
+            vnfm_info = get_vnfminfo_from_nslcm(vnfmid)
+            logger.debug("[get lcm op occ] vnfm_info=[%s]", vnfm_info)
+            ret = call_vnfm("api/vnflcm/v1/vnf_lcm_op_occs/%s" % lcmopoccid, "GET", vnfm_info)
+            if ret[0] != 0:
+                logger.error("Status code is %s. detail is %s.", ret[2], ret[1])
+                raise GvnfmDriverException("Failed to query vnf lcm op occ %s" % lcmopoccid)
+            resp_data = json.JSONDecoder().decode(ret[1])
+            vnf_lcm_op_occ_serializer = VNFLCMOpOccSerializer(data=resp_data)
+            if vnf_lcm_op_occ_serializer.is_valid():
+                logger.debug("[%s]resp_data=%s" % (fun_name(), resp_data))
+                return Response(data=vnf_lcm_op_occ_serializer.data, status=status.HTTP_200_OK)
+            else:
+                raise GvnfmDriverException(vnf_lcm_op_occ_serializer.errors)
+        except GvnfmDriverException as e:
+            logger.error("Query vnflcmopocc failed, detail message: %s" % e.message)
+            return Response(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+        except:
+            logger.error(traceback.format_exc())
+            return Response(data={'error': traceback.format_exc()}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+
+class Subscription(APIView):
+    @swagger_auto_schema(
+        request_body=LccnSubscriptionRequestSerializer(),
+        responses={
+            status.HTTP_201_CREATED: LccnSubscriptionSerializer(),
+            status.HTTP_303_SEE_OTHER: None,
+            status.HTTP_500_INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR"
+        }
+    )
+    def post(self, request, vnfmtype):
+        logger.debug("Subscription--post::> %s" % request.data)
+        logger.debug("Subscription begin!")
+        try:
+            lccn_subscription_request_serializer = LccnSubscriptionRequestSerializer(data=request.data)
+            if not lccn_subscription_request_serializer.is_valid():
+                raise GvnfmDriverException(lccn_subscription_request_serializer.error_messages)
+            resp_data = do_subscription(request.data)
+            lccn_subscription_serializer = LccnSubscriptionSerializer(data=resp_data)
+            if not lccn_subscription_serializer.is_valid():
+                logger.debug("[%s]resp_data=%s" % (fun_name(), resp_data))
+                raise GvnfmDriverException(lccn_subscription_serializer.errors)
+            logger.debug("Subscription end!")
+            return Response(data=lccn_subscription_serializer.data, status=status.HTTP_201_CREATED)
+        except GvnfmDriverException as e:
+            logger.error(e.message)
+            return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+        except Exception as e:
+            logger.error(e.message)
+            logger.error(traceback.format_exc())
+            return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
 
 def call_vnfm(resource, method, vnfm_info, data=""):
     ret = restcall.call_req(
@@ -278,11 +394,13 @@ def call_vnfm(resource, method, vnfm_info, data=""):
 def mapping_conv(keyword_map, rest_return):
     resp_data = {}
     for param in keyword_map:
-        if keyword_map[param]:
-            if isinstance(keyword_map[param], dict):
-                resp_data[param] = mapping_conv(keyword_map[param], ignorcase_get(rest_return, param))
-            else:
-                resp_data[param] = ignorcase_get(rest_return, param)
+        # if keyword_map[param]:
+        if isinstance(keyword_map[param], dict):
+            resp_data[param] = mapping_conv(keyword_map[param], ignorcase_get(rest_return, param))
+        else:
+            value = ignorcase_get(rest_return, param)
+            if value:
+                resp_data[param] = value
     return resp_data
 
 
@@ -305,7 +423,8 @@ def ignorcase_get(args, key):
 
 def get_vnfminfo_from_nslcm(vnfm_id):
     logger.debug("[get_vnfminfo_from_nslcm] vnfm_id=[%s]", vnfm_id)
-    ret = req_by_msb("api/aai-esr-server/v1/vnfms/%s" % vnfm_id, "GET")
+    # ret = req_by_msb("api/aai-esr-server/v1/vnfms/%s" % vnfm_id, "GET")
+    ret = req_by_msb("api/nslcm/v1/vnfms/%s" % vnfm_id, "GET")
     logger.debug("[get_vnfminfo_from_nslcm] response=%s", ret)
     if ret[0] != 0:
         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
@@ -408,3 +527,13 @@ def do_queryvnf(data, vnfm_id, vnfInstanceId):
         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
         raise GvnfmDriverException('Failed to query vnf.')
     return json.JSONDecoder().decode(ret[1])
+
+
+def do_subscription(data):
+    logger.debug("[%s] request.data=%s", fun_name(), data)
+    ret = req_by_msb("api/vnflcm/v1/subscriptions", "POST", json.JSONEncoder().encode(data))
+    logger.debug("[%s] call_req ret=%s", fun_name(), ret)
+    if ret[0] != 0:
+        logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
+        raise GvnfmDriverException('Failed to subscribe.')
+    return json.JSONDecoder().decode(ret[1])