650d2afc991e45df93757b549c9ca629181a1c88
[vfc/nfvo/lcm.git] / lcm / pub / utils / jobutil.py
1 # Copyright 2016-2017 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 import datetime
15 import logging
16 import uuid
17 import traceback
18
19 from lcm.pub.database.models import JobStatusModel, JobModel
20 from lcm.pub.utils import idutil
21
22 logger = logging.getLogger(__name__)
23
24
25 def enum(**enums):
26     return type('Enum', (), enums)
27
28
29 JOB_STATUS = enum(PROCESSING=0, FINISH=1)
30 JOB_MODEL_STATUS = enum(STARTED='started', PROCESSING='processing', FINISHED='finished', ERROR='error',
31                         TIMEOUT='timeout')
32 JOB_TYPE = enum(CREATE_VNF="create vnf", TERMINATE_VNF="terminate vnf", GRANT_VNF="grant vnf", MANUAL_SCALE_VNF="manual scale vnf")
33
34
35 class JobUtil(object):
36     def __init__(self):
37         pass
38
39     @staticmethod
40     def __gen_job_id(job_name):
41         return "%s-%s" % (job_name if job_name else "UnknownJob", uuid.uuid1())
42
43     @staticmethod
44     def query_job_status(job_id, index_id=-1):
45         #logger.info("Query job status, jobid =[%s], responseid [%d]" % (job_id, index_id))
46         jobs = []
47         if index_id < 0:
48             row = JobStatusModel.objects.filter(jobid=job_id).order_by("-indexid").first()
49             if row:
50                 jobs.append(row)
51         else:
52             [jobs.append(job) for job in JobStatusModel.objects.filter(jobid=job_id).order_by("-indexid")
53              if job.indexid > index_id]
54
55         #logger.info("Query job status, rows=%s" % str(jobs))
56         return jobs
57
58     @staticmethod
59     def is_job_exists(job_id):
60         jobs = JobModel.objects.filter(jobid=job_id)
61         return len(jobs) > 0
62
63     @staticmethod
64     def create_job(inst_type, jobaction, inst_id, user='', job_id=None, res_name=''):
65         if job_id is None:
66             job_id = JobUtil.__gen_job_id(
67                 '%s-%s-%s' % (str(inst_type).replace(' ', '_'), str(jobaction).replace(' ', '_'), str(inst_id)))
68         job = JobModel()
69         job.jobid = job_id
70         job.jobtype = inst_type
71         job.jobaction = jobaction
72         job.resid = str(inst_id)
73         job.status = JOB_STATUS.PROCESSING
74         job.user = user
75         job.starttime = datetime.datetime.now().strftime('%Y-%m-%d %X')
76         job.progress = 0
77         job.resname = res_name
78         logger.debug("create a new job, jobid=%s, jobtype=%s, jobaction=%s, resid=%s, status=%d" %
79                      (job.jobid, job.jobtype, job.jobaction, job.resid, job.status))
80         job.save()
81         return job_id
82
83     @staticmethod
84     def clear_job(job_id):
85         [job.delete() for job in JobModel.objects.filter(jobid=job_id)]
86         logger.debug("Clear job, job_id=%s" % job_id)
87
88     @staticmethod
89     def add_job_status(job_id, progress, status_decs, error_code=""):
90         jobs = JobModel.objects.filter(jobid=job_id)
91         if not jobs:
92             logger.error("Job[%s] is not exists, please create job first." % job_id)
93             raise Exception("Job[%s] is not exists." % job_id)
94         try:
95             int_progress = int(progress)
96             job_status = JobStatusModel()
97             job_status.indexid = int(idutil.get_auto_id(job_id))
98             job_status.jobid = job_id
99             job_status.status = "processing"
100             job_status.progress = int_progress
101
102             if job_status.progress == 0:
103                 job_status.status = "started"
104             elif job_status.progress == 100:
105                 job_status.status = "finished"
106             elif job_status.progress == 101:
107                 job_status.status = "partly_finished"
108             elif job_status.progress > 101:
109                 job_status.status = "error"
110
111             if error_code == "255":
112                 job_status.status = "error"
113
114             job_status.descp = status_decs
115             job_status.errcode = error_code
116             job_status.addtime = datetime.datetime.now().strftime('%Y-%m-%d %X')
117             job_status.save()
118             logger.debug("Add a new job status, jobid=%s, indexid=%d,"
119                          " status=%s, description=%s, progress=%d, errcode=%s, addtime=%r" %
120                          (job_status.jobid, job_status.indexid, job_status.status, job_status.descp,
121                           job_status.progress, job_status.errcode, job_status.addtime))
122
123             job = jobs[0]
124             job.progress = int_progress
125             if job_status.progress >= 100:
126                 job.status = JOB_STATUS.FINISH
127                 job.endtime = datetime.datetime.now().strftime('%Y-%m-%d %X')
128             job.save()
129             logger.debug("update job, jobid=%s, progress=%d" % (job_status.jobid, int_progress))
130         except:
131             logger.error(traceback.format_exc())
132
133     @staticmethod
134     def clear_job_status(job_id):
135         [job.delete() for job in JobStatusModel.objects.filter(jobid=job_id)]
136         logger.debug("Clear job status, job_id=%s" % job_id)
137
138     @staticmethod
139     def get_unfinished_jobs(url_prefix, inst_id, inst_type):
140         jobs = JobModel.objects.filter(resid=inst_id, jobtype=inst_type, status=JOB_STATUS.PROCESSING)
141         progresses = reduce(lambda content, job: content + [url_prefix + "/" + job.jobid], jobs, [])
142         return progresses