diff --git a/server/app/app.js b/server/app/app.js index a90e04667..e7206945c 100755 --- a/server/app/app.js +++ b/server/app/app.js @@ -217,6 +217,7 @@ io.sockets.on('connection', function(socket) { var cronTabManager = require('_pr/cronjobs'); cronTabManager.start(); catalystSync.executeScheduledInstances(); +catalystSync.executeScheduledTasks(); server.listen(app.get('port'), function() { logger.debug('Express server listening on port ' + app.get('port')); }); \ No newline at end of file diff --git a/server/app/cronjobs/catalyst-scheduler/catalystScheduler.js b/server/app/cronjobs/catalyst-scheduler/catalystScheduler.js index 62371da42..24fc17c34 100644 --- a/server/app/cronjobs/catalyst-scheduler/catalystScheduler.js +++ b/server/app/cronjobs/catalyst-scheduler/catalystScheduler.js @@ -1,5 +1,6 @@ var logger = require('_pr/logger')(module); var instancesDao = require('_pr/model/classes/instance/instance'); +var taskDao = require('_pr/model/classes/tasks/tasks.js'); var schedulerService = require('_pr/services/schedulerService'); var async = require('async'); @@ -33,4 +34,34 @@ catalystSync.executeScheduledInstances = function executeScheduledInstances() { return; } }); +} + +catalystSync.executeScheduledTasks = function executeScheduledTasks() { + taskDao.getScheduledTasks(function(err, tasks) { + if (err) { + logger.error("Failed to fetch tasks: ", err); + return; + } + if (tasks && tasks.length) { + var resultList =[]; + for (var i = 0; i < tasks.length; i++) { + (function(task) { + resultList.push(function(callback){schedulerService.executeSchedulerForTasks(task,callback);}); + if(resultList.length === tasks.length){ + async.parallel(resultList,function(err,results){ + if(err){ + logger.error(err); + return; + } + logger.debug("Task Scheduler Completed"); + return; + }) + } + })(tasks[i]); + } + }else{ + logger.debug("There is no scheduled Task right now."); + return; + } + }); } \ No newline at end of file diff --git a/server/app/lib/utils/apiUtil.js b/server/app/lib/utils/apiUtil.js index 0cda9be8c..0ac9e89cd 100644 --- a/server/app/lib/utils/apiUtil.js +++ b/server/app/lib/utils/apiUtil.js @@ -32,58 +32,64 @@ var ApiUtil = function() { } return errObj; } - this.createCronJobPattern= function(scheduler,startOn){ - scheduler.repeatEvery = parseInt(scheduler.repeatEvery); - if(scheduler.repeats ==='Minutes'){ - scheduler.pattern = '*/'+scheduler.repeatEvery+' * * * *'; - }else if(scheduler.repeats ==='Hourly'){ - scheduler.pattern = '0 */'+scheduler.repeatEvery+' * * *'; - }else if(scheduler.repeats ==='Daily'){ - var startOn = Date.parse(startOn); + this.createCronJobPattern= function(scheduler){ + scheduler.cronRepeatEvery = parseInt(scheduler.cronRepeatEvery); + if(scheduler.cronFrequency ==='Minutes'){ + scheduler.pattern = '*/'+scheduler.cronRepeatEvery+' * * * *'; + }else if(scheduler.cronFrequency ==='Hourly'){ + scheduler.pattern = '0 */'+scheduler.cronRepeatEvery+' * * *'; + }else if(scheduler.cronFrequency ==='Daily'){ + var startOn = Date.parse(scheduler.cronStartOn); var startHours= startOn.getHours(); var startMinutes= startOn.getMinutes(); - scheduler.pattern = startMinutes+' '+startHours+' */'+scheduler.repeatEvery+' * *'; - }else if(scheduler.repeats ==='Weekly') { - var startOn = Date.parse(startOn); + scheduler.pattern = startMinutes+' '+startHours+' */'+scheduler.cronRepeatEvery+' * *'; + }else if(scheduler.cronFrequency ==='Weekly') { + var startOn = Date.parse(scheduler.cronStartOn); var startDay= startOn.getDay(); var startHours= startOn.getHours(); var startMinutes= startOn.getMinutes(); - if(scheduler.repeatEvery === 2) { + if(scheduler.cronRepeatEvery === 2) { scheduler.pattern = startMinutes+' '+startHours+' 8-14 * ' + startDay; - }else if(scheduler.repeatEvery === 3) { + }else if(scheduler.cronRepeatEvery === 3) { scheduler.pattern = startMinutes+' '+startHours+' 15-21 * ' + startDay; - }else if(scheduler.repeatEvery === 4) { + }else if(scheduler.cronRepeatEvery === 4) { scheduler.pattern = startMinutes+' '+startHours+' 22-28 * ' + startDay; }else{ scheduler.pattern = startMinutes+' '+startHours+' * * ' + startDay; } } - if(scheduler.repeats ==='Monthly') { - var startOn = Date.parse(startOn); + if(scheduler.cronFrequency ==='Monthly') { + var startOn = Date.parse(scheduler.cronStartOn); var startDate= startOn.getDate(); var startMonth= startOn.getMonth(); var startDay= startOn.getDay(); var startHours= startOn.getHours(); var startMinutes= startOn.getMinutes(); - if(scheduler.repeatEvery === 1) { + if(scheduler.cronRepeatEvery === 1) { scheduler.pattern = startMinutes+' '+startHours+' '+startDate+' * *'; }else{ - scheduler.pattern = startMinutes+' '+startHours+' '+startDate+' */'+scheduler.repeatEvery+' *'; + scheduler.pattern = startMinutes+' '+startHours+' '+startDate+' */'+scheduler.cronRepeatEvery+' *'; } } - if(scheduler.repeats ==='Yearly') { - var startOn = Date.parse(startOn); + if(scheduler.cronFrequency ==='Yearly') { + var startOn = Date.parse(scheduler.cronStartOn); var startDate= startOn.getDate(); var startYear= startOn.getFullYear(); var startMonth= startOn.getMonth(); var startHours= startOn.getHours(); var startMinutes= startOn.getMinutes(); - scheduler.pattern ='0 '+startMinutes+' '+startHours+' '+startDate+' '+startMonth+' ? '+startYear/scheduler.repeatEvery; + scheduler.pattern ='0 '+startMinutes+' '+startHours+' '+startDate+' '+startMonth+' ? '+startYear/scheduler.cronRepeatEvery; } var cronScheduler = { - "repeats": scheduler.repeats, - "repeatEvery": scheduler.repeatEvery, - "cronPattern":scheduler.pattern + "cronFrequency": scheduler.cronFrequency, + "cronRepeatEvery": scheduler.cronRepeatEvery, + "cronPattern":scheduler.pattern, + "cronStartOn":Date.parse(scheduler.cronStartOn), + "cronEndOn":Date.parse(scheduler.cronEndOn), + "cronTime":scheduler.cronTime, + "cronDays":scheduler.cronDays, + "cronMonths":scheduler.cronMonths, + "cronYears":scheduler.cronYears } return cronScheduler; } diff --git a/server/app/model/classes/tasks/tasks.js b/server/app/model/classes/tasks/tasks.js index 26f2032ed..2aedacc02 100755 --- a/server/app/model/classes/tasks/tasks.js +++ b/server/app/model/classes/tasks/tasks.js @@ -130,6 +130,63 @@ var taskSchema = new Schema({ type: String, required: true, trim: true + }, + isTaskScheduled:{ + type: Boolean, + required: false, + default:false + }, + taskScheduler:{ + cronStartOn: { + type: Number, + required: false, + trim: true + }, + cronEndOn: { + type: Number, + required: false, + trim: true + }, + cronPatten: { + type: String, + required: false, + trim: true + }, + cronRepeatEvery: { + type: Number, + required: false, + trim: true + }, + cronFrequency: { + type: Number, + required: false, + trim: true + }, + cronTime:{ + type: String, + required: false, + trim: true + }, + cronDays:{ + type: String, + required: false, + trim: true + }, + cronMonth:{ + type: String, + required: false, + trim: true + }, + cronYear:{ + type: String, + required: false, + trim: true + } + }, + cronJobId:{ + type: String, + required: false, + trim: true } }); taskSchema.plugin(mongoosePaginate); @@ -855,6 +912,52 @@ taskSchema.statics.updateTaskConfig = function updateTaskConfig(taskId, taskConf }); }; +taskSchema.statics.getScheduledTasks = function getScheduledTasks(callback) { + Tasks.find({ + isTaskScheduled: true + }, function (err, tasks) { + if (err) { + logger.error(err); + return callback(err, null); + } + return callback(null, tasks); + }) +} + +taskSchema.statics.updateCronJobIdByTaskId = function updateCronJobIdByTaskId(taskId, cronJobId, callback) { + Tasks.update({ + "_id": new ObjectId(taskId), + }, { + $set: { + cronJobId: cronJobId + } + }, { + upsert: false + }, function (err, data) { + if (err) { + callback(err, null); + return; + } + callback(null, data); + }); +}; +taskSchema.statics.updateTaskScheduler = function updateTaskScheduler(taskId, callback) { + Tasks.update({ + "_id": new ObjectId(taskId), + }, { + $set: { + isTaskScheduled: false + } + }, { + upsert: false + }, function (err, data) { + if (err) { + callback(err, null); + return; + } + callback(null, data); + }); +}; function filterScriptTaskData(data,callback){ var taskList = []; diff --git a/server/app/routes/v1.0/routes_organizations.js b/server/app/routes/v1.0/routes_organizations.js index 7e81e4253..ec38f02f0 100755 --- a/server/app/routes/v1.0/routes_organizations.js +++ b/server/app/routes/v1.0/routes_organizations.js @@ -49,6 +49,7 @@ var Docker = require('_pr/model/docker.js'); var orgValidator = require('_pr/validators/organizationValidator'); var validate = require('express-validation'); var taskService = require('_pr/services/taskService'); +var schedulerService = require('_pr/services/schedulerService'); var instanceLogModel = require('_pr/model/log-trail/instanceLog.js'); var compositeBlueprintModel = require('_pr/model/composite-blueprints/composite-blueprints.js'); var Cryptography = require('_pr/lib/utils/cryptography'); @@ -974,6 +975,10 @@ module.exports.setRoutes = function(app, sessionVerification) { taskData.orgName = project[0].orgname; taskData.bgName = project[0].productgroupname; taskData.projectName = project[0].projectname; + if(req.body.taskScheduler && req.body.taskScheduler !== null) { + taskData.taskScheduler = apiUtil.createCronJobPattern(req.body.taskScheduler); + taskData.isTaskScheduled = true; + } configmgmtDao.getEnvNameFromEnvId(req.params.envId, function(err, envName) { if (err) { res.status(500).send("Failed to fetch ENV: ", err); @@ -994,6 +999,13 @@ module.exports.setRoutes = function(app, sessionVerification) { res.status(500).send("Failed to create task: ", err); return; } + if(task.isTaskScheduled === true){ + schedulerService.executeSchedulerForTasks(task,function(err,data){ + if(err){ + logger.error("Error in executing task scheduler"); + } + }) + }; res.send(task); logger.debug("Exit post() for /organizations/%s/businessGroups/%s/projects/%s/environments/%s/tasks", req.params.orgId, req.params.bgId, req.params.projectId, req.params.environments); }); @@ -1006,6 +1018,13 @@ module.exports.setRoutes = function(app, sessionVerification) { res.status(500).send("Failed to create task: ", err); return; } + if(task.isTaskScheduled === true){ + schedulerService.executeSchedulerForTasks(task,function(err,data){ + if(err){ + logger.error("Error in executing task scheduler"); + } + }) + }; res.send(task); logger.debug("Exit post() for /organizations/%s/businessGroups/%s/projects/%s/environments/%s/tasks", req.params.orgId, req.params.bgId, req.params.projectId, req.params.environments); }); diff --git a/server/app/routes/v1.0/routes_tasks.js b/server/app/routes/v1.0/routes_tasks.js index 3f704cf46..69b76cd2b 100755 --- a/server/app/routes/v1.0/routes_tasks.js +++ b/server/app/routes/v1.0/routes_tasks.js @@ -27,6 +27,7 @@ var taskService = require('_pr/services/taskService.js') var async = require('async'); var apiUtil = require('_pr/lib/utils/apiUtil.js'); var Cryptography = require('_pr/lib/utils/cryptography'); +var schedulerService = require('_pr/services/schedulerService'); @@ -515,6 +516,10 @@ module.exports.setRoutes = function(app, sessionVerification) { app.post('/tasks/:taskId/update', function(req, res) { var taskData = req.body.taskData; + if(taskData.taskScheduler && taskData.taskScheduler !== null) { + taskData.taskScheduler = apiUtil.createCronJobPattern(taskData.taskScheduler); + taskData.isTaskScheduled = true; + } if (taskData.taskType === 'script') { Tasks.getTaskById(req.params.taskId, function(err, scriptTask) { if (err) { @@ -536,6 +541,13 @@ module.exports.setRoutes = function(app, sessionVerification) { return; } if (updateCount) { + if(taskData.isTaskScheduled === true){ + schedulerService.executeSchedulerForTasks(task,function(err,data){ + if(err){ + logger.error("Error in executing task scheduler"); + } + }) + }; res.send({ updateCount: updateCount }); @@ -554,6 +566,13 @@ module.exports.setRoutes = function(app, sessionVerification) { return; } if (updateCount) { + if(taskData.isTaskScheduled === true){ + schedulerService.executeSchedulerForTasks(task,function(err,data){ + if(err){ + logger.error("Error in executing task scheduler"); + } + }) + }; res.send({ updateCount: updateCount }); diff --git a/server/app/services/blueprintService.js b/server/app/services/blueprintService.js index 32a290b27..80c2b8df3 100644 --- a/server/app/services/blueprintService.js +++ b/server/app/services/blueprintService.js @@ -87,7 +87,7 @@ blueprintService.getAllServiceDeliveryBlueprint = function getAllServiceDelivery var results = []; if (auditTrailList.length > 0) { for (var i = 0; i < auditTrailList.length; i++) { - if (taskIds.indexOf(auditTrailList[i].auditId) > -1) { + if (blueprintIds.indexOf(auditTrailList[i].auditId) < 0) { results.push(auditTrailList[i].auditId); blueprintIds.push(auditTrailList[i].auditId); } else { diff --git a/server/app/services/schedulerService.js b/server/app/services/schedulerService.js index bcb640344..c1a582748 100644 --- a/server/app/services/schedulerService.js +++ b/server/app/services/schedulerService.js @@ -21,6 +21,7 @@ const errorType = 'schedulerService'; var schedulerService = module.exports = {}; var cronTab = require('node-crontab'); var instancesDao = require('_pr/model/classes/instance/instance'); +var taskDao = require('_pr/model/classes/tasks/tasks.js'); var async = require('async'); var instanceLogModel = require('_pr/model/log-trail/instanceLog.js'); var logsDao = require('_pr/model/dao/logsdao.js'); @@ -36,8 +37,10 @@ var azureProvider = require('_pr/model/classes/masters/cloudprovider/azureCloudP var azureCloud = require('_pr/lib/azure'); var fs = require('fs'); var providerService = require('_pr/services/providerService.js'); +var taskService = require('_pr/services/taskService.js'); var gcpProviderModel = require('_pr/model/v2.0/providers/gcp-providers'); var GCP = require('_pr/lib/gcp.js'); +var crontab = require('node-crontab'); schedulerService.executeSchedulerForInstances = function executeSchedulerForInstances(instance,callback) { logger.debug("Instance Scheduler is started for Instance. "+instance.platformId); @@ -96,6 +99,47 @@ schedulerService.executeSchedulerForInstances = function executeSchedulerForInst }) } +schedulerService.executeSchedulerForTasks = function executeSchedulerForTasks(task,callback) { + logger.debug("Task Scheduler is started for Task. "+task.name); + var currentDate = new Date(); + if(currentDate >= task.taskScheduler.cronEndOn){ + crontab.cancelJob(task.cronJobId); + taskDao.updateTaskScheduler(task._id,function(err, updatedData) { + if (err) { + logger.error("Failed to update Task Scheduler: ", err); + callback(err,null); + return; + } + logger.debug("Scheduler is ended on for Task. "+task.name); + callback(null,updatedData); + return; + }); + }else{ + var schedulerService = require('_pr/services/schedulerService'); + var cronJobId = cronTab.scheduleJob(task.taskScheduler.cronPattern, function () { + taskDao.updateCronJobIdByTaskId(task._id,cronJobId,function(err,data){ + if(err){ + logger.error("Error in updating cron job Ids. "+err); + } + }) + taskService.executeTask(task._id, "superadmin", "", "", "","","",function(err, historyData) { + if (err === 404) { + logger.error("Task not found.", err); + callback(err,null); + return; + } else if (err) { + logger.error("Failed to execute task.", err); + callback(err,null); + return; + } + logger.debug("Task Execution Success: ", task.name); + callback(null,historyData); + return; + }); + }); + } +} + schedulerService.startStopInstance= function startStopInstance(instanceId,catUser,action,callback){ logger.debug(action+ " is Starting"); async.waterfall([ @@ -142,6 +186,23 @@ schedulerService.startStopInstance= function startStopInstance(instanceId,catUse }) } +function createCronJob(cronPattern,instanceId,catUser,action,callback){ + var schedulerService = require('_pr/services/schedulerService'); + var cronJobId = cronTab.scheduleJob(cronPattern, function () { + instancesDao.updateCronJobIdByInstanceId(instanceId,cronJobId,function(err,data){ + if(err){ + logger.error("Error in updating cron job Ids. "+err); + } + }) + schedulerService.startStopInstance(instanceId, catUser, action, function (err, data) { + if (err) { + callback(err, null); + } + callback(null, cronJobId); + }); + }); +} + function startStopManagedInstance(instance,catUser,action,callback){ var actionStartLog = '',actionCompleteLog='',actionFailedLog='',vmWareAction='',instanceState='',actionLog = null; var timestampStarted = new Date().getTime(); @@ -634,21 +695,5 @@ function checkSuccessInstanceAction(logReferenceIds,instanceState,instanceLog,ac }); } -function createCronJob(cronPattern,instanceId,catUser,action,callback){ - var schedulerService = require('_pr/services/schedulerService'); - var cronJobId = cronTab.scheduleJob(cronPattern, function () { - instancesDao.updateCronJobIdByInstanceId(instanceId,cronJobId,function(err,data){ - if(err){ - logger.error("Error in updating cron job Ids. "+err); - } - }) - schedulerService.startStopInstance(instanceId, catUser, action, function (err, data) { - if (err) { - callback(err, null); - } - callback(null, cronJobId); - }); - }); -} diff --git a/server/app/services/taskService.js b/server/app/services/taskService.js index 04b0f49a9..b0d377646 100644 --- a/server/app/services/taskService.js +++ b/server/app/services/taskService.js @@ -62,7 +62,7 @@ taskService.getAllServiceDeliveryTask = function getAllServiceDeliveryTask(query var results = []; if (auditTrailList.length > 0) { for (var i = 0; i < auditTrailList.length; i++) { - if (taskIds.indexOf(auditTrailList[i].auditId) > -1) { + if (taskIds.indexOf(auditTrailList[i].auditId) < 0) { results.push(auditTrailList[i].auditId); taskIds.push(auditTrailList[i].auditId); } else {