57e6a6219cf6e4ab6277111e1ffd72485bec4db6
[vfc/gvnfm/vnflcm.git] / lcm / lcm / nf / views / common.py
1 # Copyright 2019 ZTE Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import traceback
16 import logging
17 import uuid
18
19 from rest_framework import status
20 from rest_framework.response import Response
21
22 from lcm.pub.exceptions import NFLCMException
23 from lcm.pub.exceptions import NFLCMExceptionPreconditionFailed
24 from lcm.pub.exceptions import NFLCMExceptionBadRequest
25 from lcm.pub.exceptions import NFLCMExceptionNotFound
26 from lcm.pub.exceptions import NFLCMExceptionConflict
27 from lcm.pub.exceptions import NFLCMExceptionSeeOther
28 from lcm.pub.database.models import NfInstModel
29 from lcm.pub.utils.jobutil import JobUtil
30 from lcm.nf.const import OPERATION_TYPE
31 from lcm.nf.serializers.vnf_instance import VnfInstanceSerializer
32
33 logger = logging.getLogger(__name__)
34
35 CACHE_ETAG = None
36
37
38 def make_error_resp(status, detail):
39     return Response(
40         data={
41             'status': status,
42             'detail': detail
43         },
44         status=status
45     )
46
47
48 def view_safe_call_with_log(logger):
49     def view_safe_call(func):
50         def wrapper(*args, **kwargs):
51             try:
52                 return func(*args, **kwargs)
53             except NFLCMExceptionSeeOther as e:
54                 logger.error(e.message)
55                 resp = Response(status=status.HTTP_303_SEE_OTHER)
56                 resp["Location"] = ""
57                 # resp["Location"] = "subscriptions/%s" % e.id
58                 return resp
59             except NFLCMExceptionNotFound as e:
60                 logger.error(e.message)
61                 return make_error_resp(
62                     detail=e.message,
63                     status=status.HTTP_404_NOT_FOUND
64                 )
65             except NFLCMExceptionBadRequest as e:
66                 logger.error(e.message)
67                 return make_error_resp(
68                     detail=e.message,
69                     status=status.HTTP_400_BAD_REQUEST
70                 )
71             except NFLCMExceptionConflict as e:
72                 logger.error(e.message)
73                 return make_error_resp(
74                     detail=e.message,
75                     status=status.HTTP_409_CONFLICT
76                 )
77             except NFLCMExceptionPreconditionFailed as e:
78                 logger.error(e.message)
79                 return make_error_resp(
80                     detail=e.message,
81                     status=status.HTTP_412_PRECONDITION_FAILED
82                 )
83             except NFLCMException as e:
84                 logger.error(e.message)
85                 return make_error_resp(
86                     detail=e.message,
87                     status=status.HTTP_500_INTERNAL_SERVER_ERROR
88                 )
89             except Exception as e:
90                 logger.error(e.message)
91                 logger.error(traceback.format_exc())
92                 return make_error_resp(
93                     detail='Unexpected exception',
94                     status=status.HTTP_500_INTERNAL_SERVER_ERROR
95                 )
96         return wrapper
97     return view_safe_call
98
99
100 def deal_vnf_action(logger, opt_type, opt_status, instid, req, req_serializer, act_task):
101     global CACHE_ETAG
102     logger.debug("%s--post::> %s, %s", opt_type, instid, req.data)
103
104     act_vnf_req_serializer = req_serializer(data=req.data)
105     if not act_vnf_req_serializer.is_valid():
106         raise NFLCMException(act_vnf_req_serializer.errors)
107
108     vnf_insts = NfInstModel.objects.filter(nfinstid=instid)
109     if not vnf_insts.exists():
110         raise NFLCMExceptionNotFound("VNF(%s) does not exist." % instid)
111
112     if opt_type == OPERATION_TYPE.INSTANTIATE:
113         if vnf_insts[0].status == 'INSTANTIATED':
114             raise NFLCMExceptionConflict("VNF(%s) is already INSTANTIATED." % instid)
115     elif opt_type != OPERATION_TYPE.MODIFY_INFO:
116         if vnf_insts[0].status != 'INSTANTIATED':
117             raise NFLCMExceptionConflict("VNF(%s) is not INSTANTIATED." % instid)
118
119     req_etag = None
120     is_upd_vnf_opt = (opt_type == "UpdateVnf")
121     if is_upd_vnf_opt:
122         req_etag = req.META.get("HTTP_IF_MATCH")
123         logger.debug("req_etag=%s, CACHE_ETAG=%s", req_etag, CACHE_ETAG)
124         if req_etag != CACHE_ETAG:
125             raise NFLCMExceptionPreconditionFailed("Etag mismatch")
126
127     job_id = JobUtil.create_job('NF', opt_type, instid)
128     JobUtil.add_job_status(job_id, 0, "VNF_%s_READY" % opt_type)
129
130     vnf_insts.update(status=opt_status)
131     act_task(req.data, instid, job_id).start()
132
133     resp = Response(data={"jobId": job_id}, status=status.HTTP_202_ACCEPTED)
134     if is_upd_vnf_opt:
135         resp["ETag"] = req_etag
136     return resp
137
138
139 def deal_indivdual_query(res_serializer, query_fun, *args):
140     global CACHE_ETAG
141
142     res = query_fun(*args)
143     resp_serializer = res_serializer(data=res)
144     if not resp_serializer.is_valid():
145         raise NFLCMException(resp_serializer.errors)
146
147     resp = Response(data=resp_serializer.data, status=status.HTTP_200_OK)
148     if res_serializer == VnfInstanceSerializer:
149         CACHE_ETAG = "%s" % uuid.uuid1()
150         logger.debug("set CACHE_ETAG = %s", CACHE_ETAG)
151         resp["ETag"] = CACHE_ETAG
152     return resp