/// <summary>
        /// Schedule a batch job
        /// </summary>
        /// <returns></returns>
        private JobConfig ScheduleSingleJob(JobDeploymentSession job, string destFolder, JsonConfig defaultJobConfig, bool isOneTime, TimeSpan interval, TimeSpan window, DateTime processTime, DateTime scheduledTime, string prefix = "")
        {
            var ps_s = processTime;
            var ps_e = processTime.Add(interval).AddMilliseconds(-1); //ENDTIME

            var pe_s = ps_s.Add(-window);
            var pe_e = ps_e.Add(-window); // STARTTIME

            var dateString = ConvertDateToString(scheduledTime);
            var suffix     = prefix + $"-{Regex.Replace(dateString, "[^0-9]", "")}";
            var jobName    = job.Name + suffix;

            job.SetStringToken("name", jobName);

            Ensure.NotNull(defaultJobConfig, "defaultJobConfig");

            var processStartTime = ConvertDateToString(pe_e);
            var processEndTime   = ConvertDateToString(ps_e);

            destFolder = GetJobConfigFilePath(isOneTime, dateString, destFolder);
            var jc = new JobConfig
            {
                Content          = GetBatchConfigContent(job, defaultJobConfig.ToString(), processStartTime, processEndTime),
                FilePath         = ResourcePathUtil.Combine(destFolder, job.Name + ".conf"),
                Name             = jobName,
                SparkJobName     = job.SparkJobName + suffix,
                ProcessStartTime = processStartTime,
                ProcessEndTime   = processEndTime,
                ProcessingTime   = dateString,
                IsOneTime        = isOneTime
            };

            return(jc);
        }
Example #2
0
        /// <summary>
        /// create or update the spark job entry for the given job in deploying
        /// </summary>
        /// <returns>name of the spark job deployed</returns>
        private async Task <string[]> DeploySingleJob(JobDeploymentSession job, JsonConfig defaultSparkJobConfig)
        {
            List <string> names = new List <string>();

            foreach (var jc in job.JobConfigs)
            {
                // For each job
                //      replace config with tokens from job and flow, and the runtime config file path
                //      create spark job entry
                job.SparkJobName           = jc.SparkJobName;
                job.SparkJobConfigFilePath = jc.SparkFilePath;
                var json        = job.Tokens.Resolve(defaultSparkJobConfig);
                var newJob      = SparkJobConfig.From(json);
                var jobName     = newJob.Name;
                var existingJob = await SparkJobData.GetByName(jobName);

                if (existingJob != null)
                {
                    //keep the state of the old job so we can stop that
                    newJob.SyncResult = existingJob.SyncResult;
                }

                var result = await this.SparkJobData.UpsertByName(jobName, newJob);

                if (!result.IsSuccess)
                {
                    throw new ConfigGenerationException($"Failed to upsert into SparkJob table for job '{jobName}': {result.Message}");
                }

                names.Add(jobName);
            }

            return(names.ToArray());
        }
        /// <summary>
        /// Generate job config with the jobs scheduled
        /// </summary>
        /// <returns></returns>
        private async Task GenerateJobConfigContent(JobDeploymentSession job, string destFolder, JsonConfig defaultJobConfig)
        {
            Ensure.NotNull(destFolder, "destFolder");
            Ensure.NotNull(defaultJobConfig, "defaultJobConfig");

            var inputConfig = job.Flow.Config?.GetGuiConfig();

            var jcons = new List <JobConfig>();

            for (int i = 0; i < inputConfig.BatchList.Length; i++)
            {
                job.JobConfigs.AddRange(await GetJobConfig(job, inputConfig.BatchList[i], destFolder, defaultJobConfig, i).ConfigureAwait(false));
            }
        }
        private void GenerateJobConfigContent(JobDeploymentSession job, string destFolder, JsonConfig defaultJobConfig)
        {
            Ensure.NotNull(destFolder, "destFolder");
            Ensure.NotNull(defaultJobConfig, "defaultJobConfig");

            // replace config with tokens from job and the flow

            var newJobConfig = job.Tokens.Resolve(defaultJobConfig);

            Ensure.NotNull(newJobConfig, "newJobConfig");
            job.SetJsonToken(TokenName_JobConfigContent, newJobConfig);

            var destinationPath = ResourcePathUtil.Combine(destFolder, job.Name + ".json");

            job.SetStringToken(TokenName_JobConfigFilePath, destinationPath);
        }
        /// <summary>
        /// Get a batch job config
        /// </summary>
        /// <returns></returns>
        private static string GetBatchConfigContent(JobDeploymentSession job, string content, string processStartTime, string processEndTime)
        {
            var specsBackup = job.GetAttachment <InputBatchingSpec[]>(TokenName_InputBatching);

            foreach (var spec in specsBackup)
            {
                spec.ProcessStartTime = processStartTime;
                spec.ProcessEndTime   = processEndTime;
            }

            job.SetObjectToken(TokenName_InputBatching, specsBackup);

            var jsonContent = job.Tokens.Resolve(content);

            return(jsonContent);
        }
        private void GenerateJobConfigContent(JobDeploymentSession job, string destFolder, JsonConfig defaultJobConfig)
        {
            Ensure.NotNull(destFolder, "destFolder");
            Ensure.NotNull(defaultJobConfig, "defaultJobConfig");

            // replace config with tokens from job and the flow

            var newJobConfig = job.Tokens.Resolve(defaultJobConfig);

            Ensure.NotNull(newJobConfig, "newJobConfig");
            job.SetJsonToken(TokenName_JobConfigContent, newJobConfig);

            var jc = new JobConfig
            {
                Content      = newJobConfig.ToString(),
                FilePath     = ResourcePathUtil.Combine(destFolder, job.Name + ".conf"),
                SparkJobName = job.SparkJobName,
            };

            job.JobConfigs.Add(jc);
        }
        /// <summary>
        /// Prepare for scheduling batch jobs
        /// e.g. Calculate the processTime and startTime and endTime
        /// </summary>
        /// <returns></returns>
        private async Task <List <JobConfig> > GetJobConfig(JobDeploymentSession job, FlowGuiInputBatchJob batchingJob,
                                                            string destFolder,
                                                            JsonConfig defaultJobConfig,
                                                            int index)
        {
            bool isOneTime  = batchingJob.Type == Constants.Batch_OneTime;
            var  jQueue     = new List <JobConfig>();
            var  batchProps = batchingJob.Properties;

            if (batchingJob.Disabled || batchProps.StartTime == null || (isOneTime && batchProps.EndTime == null))
            {
                return(jQueue);
            }

            var configStartTime = (DateTime)batchProps.StartTime;
            var configEndTime   = batchProps.EndTime;

            var interval = TranslateInterval(batchProps.Interval, batchProps.IntervalType);
            var delay    = TranslateDelay(batchProps.Delay, batchProps.DelayType);
            var window   = TranslateWindow(batchProps.Window, batchProps.WindowType);

            var currentTime = DateTime.UtcNow;

            if (!isOneTime)
            {
                if (currentTime < configStartTime || (configEndTime != null && configEndTime < currentTime))
                {
                    await DisableBatchConfig(job.Flow.Config, index).ConfigureAwait(false);

                    return(jQueue);
                }
            }

            DateTime startTime;
            DateTime?endTime;

            var prefix = "";

            if (!isOneTime)
            {
                if (string.IsNullOrEmpty(batchProps.LastProcessedTime))
                {
                    startTime = configStartTime;
                    endTime   = currentTime;
                }
                else
                {
                    var lastProcessedTimeFromConfig = UnixTimestampToDateTime(batchProps.LastProcessedTime);
                    var startTimeBasedOnLastProcessedTImeFromConfig = lastProcessedTimeFromConfig.Add(interval);

                    startTime = startTimeBasedOnLastProcessedTImeFromConfig;
                    endTime   = currentTime;
                }
            }
            else
            {
                prefix = "-OneTime";

                startTime = configStartTime;
                endTime   = configEndTime;
            }

            DateTime lastProcessingTime = new DateTime();

            for (var processingTime = startTime; processingTime <= endTime; processingTime += interval)
            {
                lastProcessingTime = processingTime;
                var       processingTimeBasedOnInterval = NormalizeTimeBasedOnInterval(processingTime, batchProps.IntervalType, new TimeSpan());
                var       processingTimeBasedOnDelay    = NormalizeTimeBasedOnInterval(processingTime, batchProps.IntervalType, delay);
                JobConfig jc = ScheduleSingleJob(job, destFolder, defaultJobConfig, isOneTime, interval, window, processingTimeBasedOnDelay, processingTimeBasedOnInterval, prefix);
                jQueue.Add(jc);
            }

            if (!isOneTime)
            {
                if (lastProcessingTime != DateTime.MinValue)
                {
                    var uTimestamp = DateTimeToUnixTimestamp(lastProcessingTime);
                    if (uTimestamp > 0)
                    {
                        var ret = await UpdateLastProcessedTime(job.Flow.Config, index, uTimestamp).ConfigureAwait(false);

                        if (!ret.IsSuccess)
                        {
                            throw new ConfigGenerationException(ret.Message);
                        }
                    }
                }
            }
            else
            {
                // OneTime
                var ret = await DisableBatchConfig(job.Flow.Config, index).ConfigureAwait(false);

                if (!ret.IsSuccess)
                {
                    throw new ConfigGenerationException(ret.Message);
                }
            }

            return(jQueue);
        }