public void GetJobRunById() { using (this.GivenRunningServerWithWebApi()) { var client = new JobbrClient(this.BackendAddress); var job = new Job(); this.JobStorage.AddJob(job); var trigger = new RecurringTrigger(); this.JobStorage.AddTrigger(job.Id, trigger); var jobRun = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id } }; this.JobStorage.AddJobRun(jobRun); var jobRunDto = client.GetJobRunById(jobRun.Id); Assert.IsNotNull(jobRunDto); Assert.AreEqual(jobRun.Id, jobRunDto.JobRunId); Assert.AreEqual(jobRun.Job.Id, jobRunDto.JobId); Assert.AreEqual(jobRun.Trigger.Id, jobRunDto.TriggerId); } }
public void GetJobRunsByTriggerId() { using (this.GivenRunningServerWithWebApi()) { var client = new JobbrClient(this.BackendAddress); var job = new Job(); this.JobStorage.AddJob(job); var trigger = new RecurringTrigger(); this.JobStorage.AddTrigger(job.Id, trigger); var jobRun = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id } }; this.JobStorage.AddJobRun(jobRun); var jobRun2 = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id } }; this.JobStorage.AddJobRun(jobRun2); var jobRuns = client.GetJobRunsByTriggerId(job.Id, trigger.Id); Assert.AreEqual(2, jobRuns.TotalItems); } }
private bool ApplyOtherChanges(RecurringTrigger fromDb, RecurringTrigger updatedOne) { bool hadChanges = false; if (!string.Equals(fromDb.Definition, updatedOne.Definition, StringComparison.OrdinalIgnoreCase)) { fromDb.Definition = updatedOne.Definition; hadChanges = true; } if (fromDb.NoParallelExecution != updatedOne.NoParallelExecution) { fromDb.NoParallelExecution = updatedOne.NoParallelExecution; hadChanges = true; } if (fromDb.StartDateTimeUtc != updatedOne.StartDateTimeUtc) { fromDb.StartDateTimeUtc = updatedOne.StartDateTimeUtc; hadChanges = true; } if (fromDb.EndDateTimeUtc != updatedOne.EndDateTimeUtc) { fromDb.EndDateTimeUtc = updatedOne.EndDateTimeUtc; hadChanges = true; } if (this.ApplyBaseChanges(fromDb, updatedOne)) { hadChanges = true; } return(hadChanges); }
public void NoParallelExecutionDisabled_ForceNewPlanWhileJobIsStillRunning_NextJobRunIsCreated() { var initialDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc); this.currentTimeProvider.Set(initialDate); var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, NoParallelExecution = false }; this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger); // Simulate that the jobRun has started var addedJobRun = this.repository.GetJobRunsByTriggerId(recurringTrigger.JobId, recurringTrigger.Id).Single(); addedJobRun.State = JobRunStates.Processing; this.repository.Update(addedJobRun); // Make sure the cron in the recurring trigger will base on an updated "now" this.currentTimeProvider.Set(initialDate.AddHours(2)); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(2, jobRuns.Count); Assert.AreEqual(2, this.lastIssuedPlan.Count, "Since one JobRun has completed, there should be now 2 jobruns"); Assert.AreEqual(2, this.repository.GetJobRuns().Count, "The recurring trigger should should have triggered 2"); Assert.AreEqual(jobRuns[0].Id, this.lastIssuedPlan[0].Id); Assert.AreEqual(jobRuns[1].Id, this.lastIssuedPlan[1].Id); }
public void JobService_ExistingRecurringTriggerIsUpdated_UpdateIsPersisted() { var demoJob = new Job(); var storageProvider = this.Services.JobStorageProvider; storageProvider.AddJob(demoJob); var definition1 = "1 1 1 1 1"; var definition2 = "1 1 1 1 3"; var initialTrigger = new RecurringTrigger { JobId = demoJob.Id, Definition = definition1, IsActive = true }; storageProvider.AddTrigger(demoJob.Id, initialTrigger); var updatedTrigger = new RecurringTrigger { Id = initialTrigger.Id, JobId = demoJob.Id, Definition = definition2, IsActive = true }; this.Services.JobManagementService.UpdateTriggerDefinition(demoJob.Id, updatedTrigger.Id, updatedTrigger.Definition); var assertTrigger = (RecurringTrigger)storageProvider.GetTriggerById(demoJob.Id, initialTrigger.Id); Assert.AreEqual(definition2, assertTrigger.Definition); }
public void Delete_Job_Run() { using (this.GivenRunningServerWithWebApi()) { var client = new JobbrClient(this.BackendAddress); var job = new Job(); this.JobStorage.AddJob(job); var trigger = new RecurringTrigger(); this.JobStorage.AddTrigger(job.Id, trigger); var jobRun = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id }, State = JobRunStates.Completed }; this.JobStorage.AddJobRun(jobRun); client.DeleteJobRun(jobRun.Id); var jobRun2 = this.JobStorage.GetJobRunById(jobRun.Id); Assert.IsTrue(jobRun2.Deleted); } }
public void RecurringTrigger_WhenAddedBeforeStart_ShouldTriggerOneRun() { this.scheduler.Stop(); var futureDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc); this.currentTimeProvider.Set(futureDate); var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true }; // This triggers the first jobrun this.repository.SaveAddTrigger(this.demoJob1Id, recurringTrigger); this.scheduler.Start(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(1, jobRuns.Count, "There should only be one jobrun"); Assert.AreEqual(futureDate.Date, jobRuns[0].PlannedStartDateTimeUtc.Date); Assert.AreEqual(futureDate.Hour, jobRuns[0].PlannedStartDateTimeUtc.Hour); Assert.AreEqual(futureDate.Minute + 1, jobRuns[0].PlannedStartDateTimeUtc.Minute); Assert.AreEqual(0, jobRuns[0].PlannedStartDateTimeUtc.Second); }
public void HasTriggerWithJobId_QueryByMatchingJobId_ReturnsListWithSingle() { // Arrange var instantTrigger = new InstantTrigger { IsActive = true }; var recurringTrigger = new RecurringTrigger() { IsActive = true }; var scheduledTrigger = new ScheduledTrigger { IsActive = true }; this.Services.JobStorageProvider.AddTrigger(100, instantTrigger); this.Services.JobStorageProvider.AddTrigger(200, recurringTrigger); this.Services.JobStorageProvider.AddTrigger(300, scheduledTrigger); // Act var triggers = this.QueryService.GetTriggersByJobId(200, 1, 50).Items; var assertingRecurringTrigger = triggers[0] as ComponentModel.Management.Model.RecurringTrigger; // Test Assert.IsNotNull(triggers); Assert.AreEqual(1, triggers.Count); Assert.AreEqual(recurringTrigger.Id, assertingRecurringTrigger.Id); }
public void NoParallelExecutionEnabled_TriggerWhileJobIsStillRunning_NextJobRunIsPrevented() { var initialDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc); this.currentTimeProvider.Set(initialDate); var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, NoParallelExecution = true }; // This triggers the first jobrun this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger); // Simulate that the jobRun has started var addedJobRun = this.repository.GetJobRunsByTriggerId(recurringTrigger.JobId, recurringTrigger.Id).Single(); addedJobRun.State = JobRunStates.Processing; this.repository.Update(addedJobRun); // Make sure the cron in the recurring trigger will base on an updated "now" this.currentTimeProvider.Set(initialDate.AddHours(2)); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(1, jobRuns.Count, "Creating new jobruns should be prevented if a JobRun is not yet completed for the trigger"); Assert.AreEqual(1, this.lastIssuedPlan.Count, "It doesn't mather how often the Callback for recurring trigger scheduling is called, as long as there is a job running, there shoulnd be any additional jobs"); }
public void RecurringTrigger_AfterTwoMinutes_IsPlannedMultipleTimes() { var dateTimeUtc = new DateTime(2017, 02, 09, 14, 00, 00); this.currentTimeProvider.Set(dateTimeUtc); var scheduledTrigger = new RecurringTrigger() { Definition = "* * * * *", JobId = this.demoJob1Id, StartDateTimeUtc = dateTimeUtc, IsActive = true }; this.AddAndSignalNewTrigger(this.demoJob1Id, scheduledTrigger); this.currentTimeProvider.AddMinute(); this.periodicTimer.CallbackOnce(); this.currentTimeProvider.AddMinute(); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); var expectedTime1 = dateTimeUtc.AddMinutes(1); var expectedTime2 = dateTimeUtc.AddMinutes(2); var expectedTime3 = dateTimeUtc.AddMinutes(3); Assert.AreEqual(3, jobRuns.Count); Assert.AreEqual(expectedTime1, this.lastIssuedPlan[0].PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute"); Assert.AreEqual(expectedTime2, this.lastIssuedPlan[1].PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute"); Assert.AreEqual(expectedTime3, this.lastIssuedPlan[2].PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute"); }
public void AddTrigger(long jobId, RecurringTrigger trigger) { var newTriggerId = this.localTriggers.Count + 1; trigger.Id = newTriggerId; trigger.JobId = jobId; this.localTriggers.Add(trigger); }
internal static RecurringTrigger ConvertToTrigger(RecurringTriggerDto dto) { var trigger = new RecurringTrigger { Definition = dto.Definition, StartDateTimeUtc = dto.StartDateTimeUtc, EndDateTimeUtc = dto.EndDateTimeUtc }; return((RecurringTrigger)MapCommonValues(dto, trigger)); }
internal static RecurringTriggerDto ConvertToDto(RecurringTrigger trigger) { var dto = new RecurringTriggerDto { StartDateTimeUtc = trigger.StartDateTimeUtc, EndDateTimeUtc = trigger.EndDateTimeUtc, Definition = trigger.Definition }; return((RecurringTriggerDto)MapCommonValues(trigger, dto)); }
public void Update(long jobId, RecurringTrigger trigger) { using (var connection = this.connectionFactory.Open()) { var entity = trigger.ToEntity(); connection.Update(entity); } }
public void AddTrigger(long jobId, RecurringTrigger trigger) { var model = this.mapper.Map <RecurringTriggerModel>(trigger); this.triggerService.Add(jobId, model); trigger.Id = model.Id; trigger.JobId = jobId; }
private bool ApplyOtherChanges(RecurringTrigger fromDb, RecurringTrigger updatedOne) { if (!string.Equals(fromDb.Definition, updatedOne.Definition, StringComparison.OrdinalIgnoreCase)) { fromDb.Definition = updatedOne.Definition; return(true); } return(false); }
internal PlanResult Plan(RecurringTrigger trigger) { if (!trigger.IsActive) { return(PlanResult.FromAction(PlanAction.Obsolete)); } if (trigger.EndDateTimeUtc.HasValue && trigger.EndDateTimeUtc.Value < this.dateTimeProvider.GetUtcNow()) { // This jobrun is not valid anymore return(PlanResult.FromAction(PlanAction.Obsolete)); } if (trigger.NoParallelExecution) { // find jobs that are running right now based on this trigger var hasRunningJob = this.jobbrRepository.GetRunningJobs(trigger.JobId, trigger.Id).Any(); if (hasRunningJob) { var job = this.jobbrRepository.GetJob(trigger.JobId); Logger.InfoFormat( "No Parallel Execution: prevented planning of new JobRun for Job '{0}' (JobId: {1}). Caused by trigger with id '{2}' (Type: '{3}', userId: '{4}', userName: '******')", job.UniqueName, job.Id, trigger.Id, trigger.GetType().Name, trigger.UserId, trigger.UserDisplayName); return(PlanResult.FromAction(PlanAction.Blocked)); } } DateTime baseTime; // Calculate the next occurance based on current time or possible future startdate if (trigger.StartDateTimeUtc.HasValue && trigger.StartDateTimeUtc.Value > this.dateTimeProvider.GetUtcNow()) { baseTime = trigger.StartDateTimeUtc.Value; } else { baseTime = this.dateTimeProvider.GetUtcNow(); } var schedule = CrontabSchedule.Parse(trigger.Definition); return(new PlanResult { Action = PlanAction.Possible, ExpectedStartDateUtc = schedule.GetNextOccurrence(baseTime) }); }
private void InsertTrigger(RecurringTrigger trigger) { var entity = trigger.ToEntity(); if (entity.CreatedDateTimeUtc == default(DateTime)) { entity.CreatedDateTimeUtc = DateTime.UtcNow; } using (var connection = this.connectionFactory.OpenDbConnection()) { trigger.Id = connection.Insert(entity, true); } }
public void RecurringTrigger_StartAndEndDateCoversNow_DoesNotTriggerRun() { var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, StartDateTimeUtc = DateTime.UtcNow.AddDays(-1), EndDateTimeUtc = DateTime.UtcNow.AddDays(1) }; // This triggers the first jobrun this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(1, jobRuns.Count, "The trigger should cause a job run because its valid right now"); }
public void Update(long jobId, RecurringTrigger trigger) { using (var session = this._documentStore.OpenSession()) { var job = session.Load <Model.Job>(jobId); var triggerFromDb = job.RecurringTriggers.First(p => p.Id == trigger.Id); job.RecurringTriggers.Remove(triggerFromDb); var entity = trigger.ToEntity(); job.RecurringTriggers.Add(entity); session.Store(job); session.SaveChanges(); } }
public void HasOneJobWithTrigger_QueryJobByExistingId_ReturnsJobWithTrigger() { // Arrange var job = new Job(); this.Services.JobStorageProvider.AddJob(job); var trigger = new RecurringTrigger() { Definition = "* * * * *" }; this.Services.JobStorageProvider.AddTrigger(job.Id, trigger); // Act var result = this.QueryService.GetJobById(job.Id); }
public void GetRecurringTrigger() { using (this.GivenRunningServerWithWebApi()) { var client = new JobbrClient(this.BackendAddress); var job = new Job(); this.JobStorage.AddJob(job); var trigger = new RecurringTrigger(); this.JobStorage.AddTrigger(job.Id, trigger); var triggerDto = client.GetTriggerById <RecurringTriggerDto>(job.Id, trigger.Id); Assert.IsNotNull(triggerDto); Assert.AreEqual(trigger.Id, triggerDto.Id); } }
public static ComponentModel.JobStorage.Model.RecurringTrigger ToModel(this RecurringTrigger src, long jobId) { return(new ComponentModel.JobStorage.Model.RecurringTrigger { CreatedDateTimeUtc = src.CreatedDateTimeUtc, Parameters = src.Parameters, Id = src.Id, IsActive = src.IsActive, Comment = src.Comment, UserId = src.UserId, UserDisplayName = src.UserDisplayName, StartDateTimeUtc = src.StartDateTimeUtc, EndDateTimeUtc = src.EndDateTimeUtc, NoParallelExecution = src.NoParallelExecution, Definition = src.Definition, JobId = jobId }); }
public void NewRecurringTriggerWithoutSeconds_IsAdded_IsPlannedOnTime() { var dateTimeUtc = new DateTime(DateTime.UtcNow.Year + 1, 09, 02, 17, 00, 00); var scheduledTrigger = new RecurringTrigger() { Definition = "* * * * *", JobId = this.demoJob1Id, StartDateTimeUtc = dateTimeUtc, IsActive = true }; this.AddAndSignalNewTrigger(this.demoJob1Id, scheduledTrigger); var jobRun = this.repository.GetJobRuns().Single(); var expectedTime = dateTimeUtc.AddMinutes(1); Assert.AreEqual(expectedTime, this.lastIssuedPlan.Single().PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute"); Assert.AreEqual(jobRun.Id, this.lastIssuedPlan.Single().Id, "The startdate should be considered in the plan"); }
public void AddTrigger(long jobId, RecurringTrigger trigger) { using (var session = this._documentStore.OpenSession()) { var job = session.Load <Model.Job>(jobId); var entity = trigger.ToEntity(); entity.Id = ++job.LastTriggerId; entity.CreatedDateTimeUtc = DateTime.UtcNow; job.RecurringTriggers.Add(entity); session.Store(job); session.SaveChanges(); trigger.Id = entity.Id; trigger.CreatedDateTimeUtc = entity.CreatedDateTimeUtc; } }
public void Get_JobRuns_By_State() { using (this.GivenRunningServerWithWebApi()) { var client = new JobbrClient(this.BackendAddress); var job = new Job(); this.JobStorage.AddJob(job); var trigger = new RecurringTrigger(); this.JobStorage.AddTrigger(job.Id, trigger); var jobRun = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id }, State = JobRunStates.Completed }; this.JobStorage.AddJobRun(jobRun); var jobRun2 = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id }, State = JobRunStates.Completed }; this.JobStorage.AddJobRun(jobRun2); var jobRun3 = new JobRun { Job = new Job { Id = job.Id }, Trigger = new RecurringTrigger { Id = trigger.Id }, State = JobRunStates.Failed }; this.JobStorage.AddJobRun(jobRun3); var jobRuns = client.QueryJobRunsByState("Completed"); Assert.AreEqual(2, jobRuns.TotalItems); } }
public void RecurringTrigger_EndDateInPast_DoesNotTriggerRun() { var currentNow = new DateTime(2017, 02, 01, 15, 42, 00, DateTimeKind.Utc); this.currentTimeProvider.Set(currentNow); var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, EndDateTimeUtc = currentNow.AddDays(-1) }; // This triggers the first jobrun this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(0, jobRuns.Count, "The trigger is not valid anymore and should not trigger a run"); }
public void GivenRecurringTrigger_WhenUpdating_TriggerIsUpdated() { GivenRavenDb(); GivenStorageProvider(); var job1 = new Job { UniqueName = "testjob1", Type = "Jobs.Test1" }; this.StorageProvider.AddJob(job1); var trigger = new RecurringTrigger(); this.StorageProvider.AddTrigger(job1.Id, trigger); var trigger2 = (RecurringTrigger)this.StorageProvider.GetTriggerById(job1.Id, trigger.Id); var startDateTime = DateTime.UtcNow.AddHours(5); var endDateTime = DateTime.UtcNow.AddHours(7); trigger2.Comment = "bla"; trigger2.IsActive = true; trigger2.Parameters = "test-parameters"; trigger2.UserId = "ozu"; trigger2.StartDateTimeUtc = startDateTime; trigger2.Definition = "* * * * *"; trigger2.EndDateTimeUtc = endDateTime; trigger2.NoParallelExecution = true; this.StorageProvider.Update(job1.Id, trigger2); var trigger2Reloaded = (RecurringTrigger)this.StorageProvider.GetTriggerById(job1.Id, trigger2.Id); Assert.AreEqual("bla", trigger2Reloaded.Comment); Assert.IsTrue(trigger2Reloaded.IsActive); Assert.AreEqual("test-parameters", trigger2Reloaded.Parameters); Assert.AreEqual("ozu", trigger2Reloaded.UserId); Assert.AreEqual(startDateTime.ToString(CultureInfo.InvariantCulture), trigger2Reloaded.StartDateTimeUtc.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)); Assert.AreEqual(endDateTime.ToString(CultureInfo.InvariantCulture), trigger2Reloaded.EndDateTimeUtc.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)); Assert.AreEqual("* * * * *", trigger2Reloaded.Definition); Assert.IsTrue(trigger2Reloaded.NoParallelExecution); }
public void RecurringTrigger_StartDateInPast_FirstRunIsAtCurrentNow() { var currentNow = new DateTime(2017, 02, 01, 15, 42, 00, DateTimeKind.Utc); this.currentTimeProvider.Set(currentNow); var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, StartDateTimeUtc = currentNow.AddDays(-1) }; // This triggers the first jobrun this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(1, jobRuns.Count, "A startdate in the future should trigger the run"); Assert.AreEqual(currentNow.Date, jobRuns[0].PlannedStartDateTimeUtc.Date); }
public void RecurringTrigger_WhileRunIsIncomplete_ShouldNotRaiseNewRunsAtTheSameTime() { var futureDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc); this.currentTimeProvider.Set(futureDate); var recurringTrigger = new RecurringTrigger { Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true }; // This triggers the first jobrun this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger); this.currentTimeProvider.AddSecond(); this.periodicTimer.CallbackOnce(); var jobRuns = this.repository.GetJobRuns(); Assert.AreEqual(1, jobRuns.Count, "The periodic callback should not create new jobruns if they would start at the same time (== planned starttime has not changed)"); }