Search in sources :

Example 1 with ConditionContext

use of io.kestra.core.models.conditions.ConditionContext in project kestra by kestra-io.

the class ConditionServiceTest method valid.

@Test
void valid() {
    Flow flow = TestsUtils.mockFlow();
    Execution execution = TestsUtils.mockExecution(flow, ImmutableMap.of());
    RunContext runContext = runContextFactory.of(flow, execution);
    ConditionContext conditionContext = conditionService.conditionContext(runContext, flow, execution);
    List<Condition> conditions = Arrays.asList(ExecutionFlowCondition.builder().namespace(flow.getNamespace()).flowId(flow.getId()).build(), ExecutionNamespaceCondition.builder().namespace(flow.getNamespace()).build());
    boolean valid = conditionService.valid(flow, conditions, conditionContext);
    assertThat(valid, is(true));
}
Also used : ExecutionFlowCondition(io.kestra.core.models.conditions.types.ExecutionFlowCondition) ExecutionNamespaceCondition(io.kestra.core.models.conditions.types.ExecutionNamespaceCondition) Condition(io.kestra.core.models.conditions.Condition) ConditionContext(io.kestra.core.models.conditions.ConditionContext) Execution(io.kestra.core.models.executions.Execution) RunContext(io.kestra.core.runners.RunContext) Flow(io.kestra.core.models.flows.Flow) MicronautTest(io.micronaut.test.extensions.junit5.annotation.MicronautTest) Test(org.junit.jupiter.api.Test)

Example 2 with ConditionContext

use of io.kestra.core.models.conditions.ConditionContext in project kestra by kestra-io.

the class ConditionServiceTest method exception.

@Test
void exception() throws InterruptedException {
    List<LogEntry> logs = new ArrayList<>();
    logQueue.receive(logs::add);
    Flow flow = TestsUtils.mockFlow();
    Schedule schedule = Schedule.builder().id("unit").type(Schedule.class.getName()).cron("0 0 1 * *").build();
    RunContext runContext = runContextFactory.of(flow, schedule);
    ConditionContext conditionContext = conditionService.conditionContext(runContext, flow, null);
    List<Condition> conditions = Collections.singletonList(ExecutionFlowCondition.builder().namespace(flow.getNamespace()).flowId(flow.getId()).build());
    conditionService.valid(flow, conditions, conditionContext);
    Thread.sleep(250);
    assertThat(logs.stream().filter(logEntry -> logEntry.getNamespace().equals("io.kestra.core.services.ConditionServiceTest")).count(), greaterThan(0L));
    assertThat(logs.stream().filter(logEntry -> logEntry.getFlowId().equals("exception")).count(), greaterThan(0L));
}
Also used : ExecutionFlowCondition(io.kestra.core.models.conditions.types.ExecutionFlowCondition) ExecutionNamespaceCondition(io.kestra.core.models.conditions.types.ExecutionNamespaceCondition) Condition(io.kestra.core.models.conditions.Condition) ConditionContext(io.kestra.core.models.conditions.ConditionContext) Schedule(io.kestra.core.models.triggers.types.Schedule) ArrayList(java.util.ArrayList) RunContext(io.kestra.core.runners.RunContext) LogEntry(io.kestra.core.models.executions.LogEntry) Flow(io.kestra.core.models.flows.Flow) MicronautTest(io.micronaut.test.extensions.junit5.annotation.MicronautTest) Test(org.junit.jupiter.api.Test)

Example 3 with ConditionContext

use of io.kestra.core.models.conditions.ConditionContext in project kestra by kestra-io.

the class MultipleCondition method test.

/**
 * This conditions will only validate previously calculated value on
 * {@link FlowService#multipleFlowTrigger(Stream, Flow, Execution, MultipleConditionStorageInterface)}} and save on {@link MultipleConditionStorageInterface}
 * by the executor.
 * The real validation is done here.
 */
@Override
public boolean test(ConditionContext conditionContext) throws InternalException {
    Logger logger = conditionContext.getRunContext().logger();
    MultipleConditionStorageInterface multipleConditionStorage = conditionContext.getMultipleConditionStorage();
    Objects.requireNonNull(multipleConditionStorage);
    Optional<MultipleConditionWindow> triggerExecutionWindow = multipleConditionStorage.get(conditionContext.getFlow(), this.getId());
    Map<String, Boolean> results = conditions.keySet().stream().map(condition -> new AbstractMap.SimpleEntry<>(condition, (triggerExecutionWindow.isPresent() && triggerExecutionWindow.get().getResults() != null && triggerExecutionWindow.get().getResults().containsKey(condition) && triggerExecutionWindow.get().getResults().get(condition)))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    long validatedCount = results.entrySet().stream().filter(Map.Entry::getValue).count();
    boolean result = conditions.size() == validatedCount;
    if (result && logger.isDebugEnabled()) {
        logger.debug("[namespace: {}] [flow: {}] Multiple conditions validated !", conditionContext.getFlow().getNamespace(), conditionContext.getFlow().getId());
    } else if (logger.isTraceEnabled()) {
        logger.trace("[namespace: {}] [flow: {}] Multiple conditions failed ({}/{}) with '{}'", conditionContext.getFlow().getNamespace(), conditionContext.getFlow().getId(), validatedCount, conditions.size(), results);
    }
    return result;
}
Also used : NotBlank(javax.validation.constraints.NotBlank) Getter(lombok.Getter) Plugin(io.kestra.core.models.annotations.Plugin) MultipleConditionStorageInterface(io.kestra.core.models.triggers.multipleflows.MultipleConditionStorageInterface) ConditionContext(io.kestra.core.models.conditions.ConditionContext) MultipleConditionWindow(io.kestra.core.models.triggers.multipleflows.MultipleConditionWindow) NotEmpty(javax.validation.constraints.NotEmpty) FlowService(io.kestra.core.services.FlowService) Duration(java.time.Duration) Map(java.util.Map) ToString(lombok.ToString) Schema(io.swagger.v3.oas.annotations.media.Schema) Logger(org.slf4j.Logger) SuperBuilder(lombok.experimental.SuperBuilder) Condition(io.kestra.core.models.conditions.Condition) EqualsAndHashCode(lombok.EqualsAndHashCode) NotNull(javax.validation.constraints.NotNull) Execution(io.kestra.core.models.executions.Execution) Collectors(java.util.stream.Collectors) InternalException(io.kestra.core.exceptions.InternalException) PluginProperty(io.kestra.core.models.annotations.PluginProperty) Objects(java.util.Objects) AbstractMap(java.util.AbstractMap) Stream(java.util.stream.Stream) Pattern(javax.validation.constraints.Pattern) Example(io.kestra.core.models.annotations.Example) Optional(java.util.Optional) Flow(io.kestra.core.models.flows.Flow) NoArgsConstructor(lombok.NoArgsConstructor) MultipleConditionStorageInterface(io.kestra.core.models.triggers.multipleflows.MultipleConditionStorageInterface) MultipleConditionWindow(io.kestra.core.models.triggers.multipleflows.MultipleConditionWindow) ToString(lombok.ToString) Logger(org.slf4j.Logger) Map(java.util.Map) AbstractMap(java.util.AbstractMap)

Example 4 with ConditionContext

use of io.kestra.core.models.conditions.ConditionContext in project kestra by kestra-io.

the class Schedule method truePreviousNextDateWithCondition.

private Optional<ZonedDateTime> truePreviousNextDateWithCondition(ExecutionTime executionTime, ConditionContext conditionContext, ZonedDateTime toTestDate, boolean next) {
    while ((next && toTestDate.getYear() < ZonedDateTime.now().getYear() + 10) || (!next && toTestDate.getYear() > ZonedDateTime.now().getYear() - 10)) {
        Optional<ZonedDateTime> currentDate = next ? executionTime.nextExecution(toTestDate) : executionTime.lastExecution(toTestDate);
        if (currentDate.isEmpty()) {
            return currentDate;
        }
        Optional<Output> currentOutput = this.output(executionTime, currentDate.get());
        if (currentOutput.isEmpty()) {
            return Optional.empty();
        }
        ConditionContext currentConditionContext = this.conditionContext(conditionContext, currentOutput.get());
        boolean conditionResults = this.validateScheduleCondition(currentConditionContext);
        if (conditionResults) {
            return currentDate;
        }
        toTestDate = currentDate.get();
    }
    return Optional.empty();
}
Also used : ConditionContext(io.kestra.core.models.conditions.ConditionContext) ZonedDateTime(java.time.ZonedDateTime) TriggerOutput(io.kestra.core.models.triggers.TriggerOutput)

Example 5 with ConditionContext

use of io.kestra.core.models.conditions.ConditionContext in project kestra by kestra-io.

the class AbstractScheduler method handle.

private void handle() {
    if (!this.isReady) {
        log.warn("Scheduler is not ready, waiting");
    }
    metricRegistry.counter(MetricRegistry.SCHEDULER_LOOP_COUNT).increment();
    ZonedDateTime now = now();
    synchronized (this) {
        if (log.isDebugEnabled()) {
            log.debug("Scheduler next iteration for {} with {} schedulables of {} flows", now, schedulable.size(), this.flowListeners.flows().size());
        }
        // get all that is ready from evaluation
        List<FlowWithPollingTriggerNextDate> readyForEvaluate = schedulable.stream().filter(f -> conditionService.isValid(f.getFlow(), f.getTrigger(), f.getConditionContext())).map(flowWithTrigger -> FlowWithPollingTrigger.builder().flow(flowWithTrigger.getFlow()).trigger(flowWithTrigger.getTrigger()).pollingTrigger((PollingTriggerInterface) flowWithTrigger.getTrigger()).conditionContext(flowWithTrigger.getConditionContext()).triggerContext(TriggerContext.builder().namespace(flowWithTrigger.getFlow().getNamespace()).flowId(flowWithTrigger.getFlow().getId()).flowRevision(flowWithTrigger.getFlow().getRevision()).triggerId(flowWithTrigger.getTrigger().getId()).date(now()).build()).build()).filter(f -> this.isEvaluationInterval(f, now)).filter(f -> this.isExecutionNotRunning(f, now)).map(f -> {
            synchronized (this) {
                Trigger lastTrigger = this.getLastTrigger(f, now);
                return FlowWithPollingTriggerNextDate.of(f, f.getPollingTrigger().nextEvaluationDate(f.getConditionContext(), Optional.of(lastTrigger)));
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
        if (log.isDebugEnabled()) {
            log.debug("Scheduler will evaluate for {} with {} readyForEvaluate of {} schedulables", now, readyForEvaluate.size(), schedulable.size());
        }
        metricRegistry.counter(MetricRegistry.SCHEDULER_EVALUATE_COUNT).increment(readyForEvaluate.size());
        // submit ready one to cached thread pool
        readyForEvaluate.forEach(f -> {
            schedulableNextDate.put(f.getTriggerContext().uid(), f);
            if (f.getPollingTrigger().getInterval() == null) {
                try {
                    this.handleEvaluatePollingTriggerResult(this.evaluatePollingTrigger(f));
                } catch (Exception e) {
                    AbstractScheduler.logError(f, e);
                }
            } else {
                this.addToRunning(f.getTriggerContext(), now);
                ListenableFuture<SchedulerExecutionWithTrigger> result = cachedExecutor.submit(() -> this.evaluatePollingTrigger(f));
                Futures.addCallback(result, new EvaluateFuture(this, f), cachedExecutor);
            }
        });
    }
}
Also used : java.util(java.util) RunContextFactory(io.kestra.core.runners.RunContextFactory) Getter(lombok.Getter) QueueInterface(io.kestra.core.queues.QueueInterface) ZonedDateTime(java.time.ZonedDateTime) AbstractTrigger(io.kestra.core.models.triggers.AbstractTrigger) com.google.common.util.concurrent(com.google.common.util.concurrent) ConditionContext(io.kestra.core.models.conditions.ConditionContext) PollingTriggerInterface(io.kestra.core.models.triggers.PollingTriggerInterface) ApplicationContext(io.micronaut.context.ApplicationContext) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) TriggerContext(io.kestra.core.models.triggers.TriggerContext) Logger(org.slf4j.Logger) QueueFactoryInterface(io.kestra.core.queues.QueueFactoryInterface) TaskDefaultService(io.kestra.core.services.TaskDefaultService) ConditionService(io.kestra.core.services.ConditionService) java.util.concurrent(java.util.concurrent) SuperBuilder(lombok.experimental.SuperBuilder) Throwables(com.google.common.base.Throwables) Qualifiers(io.micronaut.inject.qualifiers.Qualifiers) Singleton(jakarta.inject.Singleton) Trigger(io.kestra.core.models.triggers.Trigger) Instant(java.time.Instant) Execution(io.kestra.core.models.executions.Execution) Collectors(java.util.stream.Collectors) InternalException(io.kestra.core.exceptions.InternalException) Slf4j(lombok.extern.slf4j.Slf4j) ChronoUnit(java.time.temporal.ChronoUnit) Stream(java.util.stream.Stream) Await(io.kestra.core.utils.Await) ExecutorsUtils(io.kestra.core.utils.ExecutorsUtils) RunContext(io.kestra.core.runners.RunContext) Flow(io.kestra.core.models.flows.Flow) FlowListenersInterface(io.kestra.core.services.FlowListenersInterface) MetricRegistry(io.kestra.core.metrics.MetricRegistry) AllArgsConstructor(lombok.AllArgsConstructor) Inject(jakarta.inject.Inject) NoArgsConstructor(lombok.NoArgsConstructor) PollingTriggerInterface(io.kestra.core.models.triggers.PollingTriggerInterface) AbstractTrigger(io.kestra.core.models.triggers.AbstractTrigger) Trigger(io.kestra.core.models.triggers.Trigger) ZonedDateTime(java.time.ZonedDateTime) InternalException(io.kestra.core.exceptions.InternalException)

Aggregations

ConditionContext (io.kestra.core.models.conditions.ConditionContext)6 Condition (io.kestra.core.models.conditions.Condition)4 Flow (io.kestra.core.models.flows.Flow)4 Execution (io.kestra.core.models.executions.Execution)3 RunContext (io.kestra.core.runners.RunContext)3 InternalException (io.kestra.core.exceptions.InternalException)2 ExecutionFlowCondition (io.kestra.core.models.conditions.types.ExecutionFlowCondition)2 ExecutionNamespaceCondition (io.kestra.core.models.conditions.types.ExecutionNamespaceCondition)2 MicronautTest (io.micronaut.test.extensions.junit5.annotation.MicronautTest)2 Duration (java.time.Duration)2 ZonedDateTime (java.time.ZonedDateTime)2 Collectors (java.util.stream.Collectors)2 Stream (java.util.stream.Stream)2 Getter (lombok.Getter)2 NoArgsConstructor (lombok.NoArgsConstructor)2 SuperBuilder (lombok.experimental.SuperBuilder)2 Test (org.junit.jupiter.api.Test)2 Throwables (com.google.common.base.Throwables)1 com.google.common.util.concurrent (com.google.common.util.concurrent)1 MetricRegistry (io.kestra.core.metrics.MetricRegistry)1