Search in sources :

Example 1 with JobTriggerDto

use of org.graylog.scheduler.JobTriggerDto in project graylog2-server by Graylog2.

the class EventDefinitionContextService method schedulerContext.

private ImmutableMap<String, SchedulerCtx> schedulerContext(List<EventDefinitionDto> eventDefinitions) {
    // We try to minimize database queries by fetching all required job definitions and triggers in two requests
    // TODO: Use MongoDB's $lookup aggregation operator once we switch to MongoDB 4.0 to do this with a single database query
    final Map<String, List<JobDefinitionDto>> jobDefinitions = getJobDefinitions(eventDefinitions);
    final Map<String, List<JobTriggerDto>> jobTriggers = getJobTriggers(jobDefinitions);
    final ImmutableMap.Builder<String, SchedulerCtx> ctx = ImmutableMap.builder();
    for (final EventDefinitionDto eventDefinition : eventDefinitions) {
        if (eventDefinition.id() == null) {
            // Should not happen!
            throw new IllegalStateException("Event definition doesn't have an ID: " + eventDefinition);
        }
        if (!jobDefinitions.containsKey(eventDefinition.id())) {
            ctx.put(eventDefinition.id(), SchedulerCtx.unscheduled());
            continue;
        }
        if (jobDefinitions.get(eventDefinition.id()).size() > 1) {
            throw new IllegalStateException("Cannot handle multiple job definitions for a single event definition");
        }
        final JobDefinitionDto jobDefinition = jobDefinitions.get(eventDefinition.id()).get(0);
        // DBJobTriggerService#getForJobs currently returns only one trigger. (raises an exception otherwise)
        // Once we allow multiple triggers per job definition, this code will fail.
        // TODO: Fix this code for multiple triggers per job definition
        final JobTriggerDto trigger = jobTriggers.get(jobDefinition.id()).get(0);
        if (trigger != null) {
            ctx.put(eventDefinition.id(), SchedulerCtx.scheduled(trigger, getQueuedNotifications(eventDefinition)));
        }
    }
    return ctx.build();
}
Also used : EventDefinitionDto(org.graylog.events.processor.EventDefinitionDto) JobDefinitionDto(org.graylog.scheduler.JobDefinitionDto) List(java.util.List) ImmutableMap(com.google.common.collect.ImmutableMap) JobTriggerDto(org.graylog.scheduler.JobTriggerDto)

Example 2 with JobTriggerDto

use of org.graylog.scheduler.JobTriggerDto in project graylog2-server by Graylog2.

the class EventDefinitionHandlerTest method updateWithSchedulingDisabled.

@Test
@MongoDBFixtures("event-processors.json")
public void updateWithSchedulingDisabled() {
    final String newTitle = "A NEW TITLE " + DateTime.now(DateTimeZone.UTC).toString();
    final String newDescription = "A NEW DESCRIPTION " + DateTime.now(DateTimeZone.UTC).toString();
    final EventDefinitionDto existingDto = eventDefinitionService.get("54e3deadbeefdeadbeef0000").orElse(null);
    final JobDefinitionDto existingJobDefinition = jobDefinitionService.get("54e3deadbeefdeadbeef0001").orElse(null);
    final JobTriggerDto existingTrigger = jobTriggerService.get("54e3deadbeefdeadbeef0002").orElse(null);
    final TestEventProcessorConfig existingConfig = (TestEventProcessorConfig) existingDto.config();
    final TestEventProcessorConfig newConfig = existingConfig.toBuilder().executeEveryMs(550000).searchWithinMs(800000).build();
    assertThat(existingDto).isNotNull();
    assertThat(existingJobDefinition).isNotNull();
    assertThat(existingTrigger).isNotNull();
    final EventDefinitionDto updatedDto = existingDto.toBuilder().title(newTitle).description(newDescription).config(newConfig).build();
    assertThat(handler.update(updatedDto, false)).isNotEqualTo(existingDto);
    assertThat(eventDefinitionService.get(existingDto.id())).isPresent().get().satisfies(dto -> {
        assertThat(dto.id()).isEqualTo(existingDto.id());
        assertThat(dto.title()).isEqualTo(newTitle);
        assertThat(dto.description()).isEqualTo(newDescription);
    });
    assertThat(jobDefinitionService.get("54e3deadbeefdeadbeef0001")).isNotPresent();
    assertThat(jobTriggerService.get("54e3deadbeefdeadbeef0002")).isNotPresent();
}
Also used : TestEventProcessorConfig(org.graylog.events.TestEventProcessorConfig) JobDefinitionDto(org.graylog.scheduler.JobDefinitionDto) JobTriggerDto(org.graylog.scheduler.JobTriggerDto) MongoDBFixtures(org.graylog.testing.mongodb.MongoDBFixtures) Test(org.junit.Test)

Example 3 with JobTriggerDto

use of org.graylog.scheduler.JobTriggerDto in project graylog2-server by Graylog2.

the class EventProcessorExecutionJobTest method catchupWindowTestHelper.

private void catchupWindowTestHelper(long catchUpWindowSize, long processingHopSize, long processingWindowSize) throws Exception {
    when(eventsConfigurationProvider.get()).thenReturn(EventsConfiguration.builder().eventCatchupWindow(catchUpWindowSize).build());
    // for easier testing. don't run into the previous day
    clock.plus(1, TimeUnit.MINUTES);
    final DateTime now = clock.nowUTC();
    final long processingCatchUpWindowSize = eventsConfigurationProvider.get().eventCatchupWindow();
    final int scheduleIntervalSeconds = (int) processingHopSize * 1000;
    final DateTime from = now.minus(processingWindowSize);
    final DateTime to = now;
    final DateTime triggerNextTime = now;
    final Duration timeSpentInEventProcessor = Duration.standardSeconds(7);
    final TestEventProcessorParameters eventProcessorParameters = TestEventProcessorParameters.create(from, to);
    final JobDefinitionDto jobDefinition = JobDefinitionDto.builder().id("job-1").title("Test").description("A test").config(EventProcessorExecutionJob.Config.builder().eventDefinitionId("processor-1").processingWindowSize(processingWindowSize).processingHopSize(processingHopSize).parameters(eventProcessorParameters).build()).build();
    final EventProcessorExecutionJob job = new EventProcessorExecutionJob(jobScheduleStrategies, clock, eventProcessorEngine, eventsConfigurationProvider, jobDefinition);
    final JobTriggerDto trigger = JobTriggerDto.builderWithClock(clock).id("trigger-1").jobDefinitionId(jobDefinition.id()).startTime(now).nextTime(triggerNextTime).status(JobTriggerStatus.RUNNABLE).schedule(IntervalJobSchedule.builder().interval(scheduleIntervalSeconds).unit(TimeUnit.SECONDS).build()).build();
    final JobExecutionContext jobExecutionContext = JobExecutionContext.builder().definition(jobDefinition).trigger(trigger).isRunning(new AtomicBoolean(true)).jobTriggerUpdates(new JobTriggerUpdates(clock, jobScheduleStrategies, trigger)).build();
    doAnswer(invocation -> {
        // Simulate work in the event processor
        clock.plus(timeSpentInEventProcessor.getStandardSeconds(), TimeUnit.SECONDS);
        return null;
    }).when(eventProcessorEngine).execute(any(), any());
    // Simulate that we are behind at least one `processingCatchUpWindowSize`
    clock.plus(EventsConfiguration.DEFAULT_CATCH_UP_WINDOW_MS, TimeUnit.MILLISECONDS);
    clock.plus(1, TimeUnit.MILLISECONDS);
    final JobTriggerUpdate triggerUpdate = job.execute(jobExecutionContext);
    verify(eventProcessorEngine, times(1)).execute("processor-1", eventProcessorParameters);
    assertThat(triggerUpdate.nextTime()).isPresent().get().isEqualTo(clock.nowUTC().minus(timeSpentInEventProcessor));
    if (catchUpWindowSize > processingWindowSize && processingHopSize <= processingWindowSize) {
        // We are behind at least one chunk of catchUpWindowSize
        // The new nextFrom should ignore the processingHopSize and start 1ms after the last `To` Range
        // The nextTo will be one window of the processingCatchUpWindowSize
        assertThat(triggerUpdate.data()).isPresent().get().isEqualTo(EventProcessorExecutionJob.Data.builder().timerangeFrom(to.plus(processingHopSize).minus(processingWindowSize)).timerangeTo(to.plus(processingCatchUpWindowSize)).build());
    } else {
        // If no catchup is in effect, we fall back into the configured hopping window mode.
        // With a hopping window the "to" is calculated by adding the hopSize and the "from" is based on the next "to"
        // minus the windowSize + 1 millisecond.
        assertThat(triggerUpdate.data()).isPresent().get().isEqualTo(EventProcessorExecutionJob.Data.builder().timerangeFrom(to.plus(processingHopSize).minus(processingWindowSize)).timerangeTo(to.plus(processingHopSize)).build());
    }
    assertThat(triggerUpdate.status()).isNotPresent();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JobDefinitionDto(org.graylog.scheduler.JobDefinitionDto) JobTriggerUpdates(org.graylog.scheduler.JobTriggerUpdates) JobTriggerUpdate(org.graylog.scheduler.JobTriggerUpdate) JobExecutionContext(org.graylog.scheduler.JobExecutionContext) Duration(org.joda.time.Duration) DateTime(org.joda.time.DateTime) TestEventProcessorParameters(org.graylog.events.TestEventProcessorParameters) EventProcessorExecutionJob(org.graylog.events.processor.EventProcessorExecutionJob) JobTriggerDto(org.graylog.scheduler.JobTriggerDto)

Example 4 with JobTriggerDto

use of org.graylog.scheduler.JobTriggerDto in project graylog2-server by Graylog2.

the class EventProcessorExecutionJobTest method executeWithInvalidTimerange.

@Test
public void executeWithInvalidTimerange() throws Exception {
    final DateTime now = clock.nowUTC();
    final long processingWindowSize = Duration.standardSeconds(60).getMillis();
    final long processingHopSize = Duration.standardSeconds(60).getMillis();
    final int scheduleIntervalSeconds = 1;
    // We set "from" to be AFTER "to" - this is not valid so the job should not be executed and the triggers
    // should be set to ERROR
    final DateTime from = now.plusSeconds(1);
    final DateTime to = now;
    final DateTime triggerNextTime = now;
    final TestEventProcessorParameters eventProcessorParameters = TestEventProcessorParameters.create(from, to);
    final JobDefinitionDto jobDefinition = JobDefinitionDto.builder().id("job-1").title("Test").description("A test").config(EventProcessorExecutionJob.Config.builder().eventDefinitionId("processor-1").processingWindowSize(processingWindowSize).processingHopSize(processingHopSize).parameters(eventProcessorParameters).build()).build();
    final EventProcessorExecutionJob job = new EventProcessorExecutionJob(jobScheduleStrategies, clock, eventProcessorEngine, eventsConfigurationProvider, jobDefinition);
    final JobTriggerDto trigger = JobTriggerDto.builderWithClock(clock).id("trigger-1").jobDefinitionId(jobDefinition.id()).startTime(now).nextTime(triggerNextTime).status(JobTriggerStatus.RUNNABLE).schedule(IntervalJobSchedule.builder().interval(scheduleIntervalSeconds).unit(TimeUnit.SECONDS).build()).build();
    final JobExecutionContext jobExecutionContext = JobExecutionContext.builder().definition(jobDefinition).trigger(trigger).isRunning(new AtomicBoolean(true)).jobTriggerUpdates(new JobTriggerUpdates(clock, jobScheduleStrategies, trigger)).build();
    assertThatThrownBy(() -> job.execute(jobExecutionContext)).isInstanceOf(JobExecutionException.class).hasMessageContaining("is not after").satisfies(t -> {
        final JobExecutionException e = (JobExecutionException) t;
        assertThat(e.getTrigger()).isEqualTo(trigger);
        assertThat(e.getUpdate()).satisfies(update -> {
            // When setting the status to ERROR, we will keen the last nextTime
            assertThat(update.nextTime()).isPresent().get().isEqualTo(triggerNextTime);
            assertThat(update.data()).isNotPresent();
            assertThat(update.status()).isPresent().get().isEqualTo(JobTriggerStatus.ERROR);
        });
    });
    // The engine should not be called because the timerange is invalid
    verify(eventProcessorEngine, never()).execute(any(), any());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JobExecutionException(org.graylog.scheduler.JobExecutionException) JobDefinitionDto(org.graylog.scheduler.JobDefinitionDto) JobTriggerUpdates(org.graylog.scheduler.JobTriggerUpdates) JobExecutionContext(org.graylog.scheduler.JobExecutionContext) DateTime(org.joda.time.DateTime) TestEventProcessorParameters(org.graylog.events.TestEventProcessorParameters) EventProcessorExecutionJob(org.graylog.events.processor.EventProcessorExecutionJob) JobTriggerDto(org.graylog.scheduler.JobTriggerDto) Test(org.junit.Test)

Example 5 with JobTriggerDto

use of org.graylog.scheduler.JobTriggerDto in project graylog2-server by Graylog2.

the class EventProcessorExecutionJobTest method executeWithNextTimeNotBasedOnCurrentTime.

@Test
public void executeWithNextTimeNotBasedOnCurrentTime() throws Exception {
    final DateTime now = clock.nowUTC();
    final long processingWindowSize = Duration.standardSeconds(60).getMillis();
    final long processingHopSize = Duration.standardSeconds(60).getMillis();
    final int scheduleIntervalSeconds = 1;
    final DateTime from = now.minus(processingWindowSize);
    final DateTime to = now;
    final DateTime triggerNextTime = now;
    final TestEventProcessorParameters eventProcessorParameters = TestEventProcessorParameters.create(from, to);
    final JobDefinitionDto jobDefinition = JobDefinitionDto.builder().id("job-1").title("Test").description("A test").config(EventProcessorExecutionJob.Config.builder().eventDefinitionId("processor-1").processingWindowSize(processingWindowSize).processingHopSize(processingHopSize).parameters(eventProcessorParameters).build()).build();
    final EventProcessorExecutionJob job = new EventProcessorExecutionJob(jobScheduleStrategies, clock, eventProcessorEngine, eventsConfigurationProvider, jobDefinition);
    final JobTriggerDto trigger = JobTriggerDto.builderWithClock(clock).id("trigger-1").jobDefinitionId(jobDefinition.id()).startTime(now).nextTime(triggerNextTime).status(JobTriggerStatus.RUNNABLE).schedule(IntervalJobSchedule.builder().interval(scheduleIntervalSeconds).unit(TimeUnit.SECONDS).build()).build();
    final JobExecutionContext jobExecutionContext = JobExecutionContext.builder().definition(jobDefinition).trigger(trigger).isRunning(new AtomicBoolean(true)).jobTriggerUpdates(new JobTriggerUpdates(clock, jobScheduleStrategies, trigger)).build();
    doAnswer(invocation -> {
        // Simulate work in the event processor
        clock.plus(10, TimeUnit.SECONDS);
        return null;
    }).when(eventProcessorEngine).execute(any(), any());
    final JobTriggerUpdate triggerUpdate = job.execute(jobExecutionContext);
    verify(eventProcessorEngine, times(1)).execute("processor-1", eventProcessorParameters);
    // The next time should be based on the previous nextTime + the schedule. The 10 second event processor
    // runtime should not be added to the new nextTime.
    assertThat(triggerUpdate.nextTime()).isPresent().get().isEqualTo(triggerNextTime.plusSeconds(scheduleIntervalSeconds));
    assertThat(triggerUpdate.data()).isPresent().get().isEqualTo(EventProcessorExecutionJob.Data.builder().timerangeFrom(to).timerangeTo(to.plus(processingWindowSize)).build());
    assertThat(triggerUpdate.status()).isNotPresent();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JobDefinitionDto(org.graylog.scheduler.JobDefinitionDto) JobTriggerUpdates(org.graylog.scheduler.JobTriggerUpdates) JobTriggerUpdate(org.graylog.scheduler.JobTriggerUpdate) JobExecutionContext(org.graylog.scheduler.JobExecutionContext) DateTime(org.joda.time.DateTime) TestEventProcessorParameters(org.graylog.events.TestEventProcessorParameters) EventProcessorExecutionJob(org.graylog.events.processor.EventProcessorExecutionJob) JobTriggerDto(org.graylog.scheduler.JobTriggerDto) Test(org.junit.Test)

Aggregations

JobTriggerDto (org.graylog.scheduler.JobTriggerDto)19 JobDefinitionDto (org.graylog.scheduler.JobDefinitionDto)15 Test (org.junit.Test)12 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)8 TestEventProcessorParameters (org.graylog.events.TestEventProcessorParameters)8 EventProcessorExecutionJob (org.graylog.events.processor.EventProcessorExecutionJob)8 JobExecutionContext (org.graylog.scheduler.JobExecutionContext)8 JobTriggerUpdates (org.graylog.scheduler.JobTriggerUpdates)8 DateTime (org.joda.time.DateTime)8 JobTriggerUpdate (org.graylog.scheduler.JobTriggerUpdate)7 TestEventProcessorConfig (org.graylog.events.TestEventProcessorConfig)3 EventDefinitionDto (org.graylog.events.processor.EventDefinitionDto)3 MongoDBFixtures (org.graylog.testing.mongodb.MongoDBFixtures)3 JobExecutionException (org.graylog.scheduler.JobExecutionException)2 NotFoundException (org.graylog2.database.NotFoundException)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 List (java.util.List)1 Event (org.graylog.events.event.Event)1 EventDto (org.graylog.events.event.EventDto)1 EventWithContext (org.graylog.events.event.EventWithContext)1