From 25763dba94566f7198009096040f22abb85e8686 Mon Sep 17 00:00:00 2001 From: Ludovic DEHON Date: Fri, 7 Jul 2023 19:24:20 +0200 Subject: [PATCH 01/16] fix(ui): missing task run value on log list --- ui/src/components/logs/LogList.vue | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ui/src/components/logs/LogList.vue b/ui/src/components/logs/LogList.vue index 5e741d4c860..5e6fc2a58af 100644 --- a/ui/src/components/logs/LogList.vue +++ b/ui/src/components/logs/LogList.vue @@ -42,10 +42,12 @@ {{ $t("duration") }}: {{ $filters.humanizeDuration(attempt.state.duration) }} - {{ currentTaskRun.taskId }} - - {{ currentTaskRun.value }} - + + {{ currentTaskRun.taskId }} + + {{ currentTaskRun.value }} + + From 9d8300153bbbeb2423ea9f4c6c26d8d3dfade361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Fri, 7 Jul 2023 15:22:38 +0200 Subject: [PATCH 02/16] fix(core): remove misleading default value for polling triggers --- .../kestra/core/models/triggers/PollingTriggerInterface.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/io/kestra/core/models/triggers/PollingTriggerInterface.java b/core/src/main/java/io/kestra/core/models/triggers/PollingTriggerInterface.java index 2fa95ec219c..892283211f4 100644 --- a/core/src/main/java/io/kestra/core/models/triggers/PollingTriggerInterface.java +++ b/core/src/main/java/io/kestra/core/models/triggers/PollingTriggerInterface.java @@ -21,8 +21,7 @@ default ZonedDateTime nextEvaluationDate(ConditionContext conditionContext, Opti description = "The interval between 2 different test of schedule, this can avoid to overload the remote system " + "with too many call. For most of trigger that depend on external system, a minimal interval must be " + "at least PT30S.\n" + - "See [ISO_8601 Durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) for more information of available interval value", - defaultValue = "PT1S" + "See [ISO_8601 Durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) for more information of available interval value" ) @PluginProperty Duration getInterval(); From 1132b0309f24f55cb7a95b462d0bcf484bd6f2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Fri, 7 Jul 2023 15:32:35 +0200 Subject: [PATCH 03/16] chore: always pull the image as we don't use the latest tag. --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 9a082a7c928..fb5fb6c17ff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: kestra: image: kestra/kestra:latest-full + pull_policy: always entrypoint: /bin/bash # Note that this is meant for development only. Refer to the documentation for production deployments of Kestra which runs without a root user. user: "root" From 9845b8302471eaeece445d66d10ff7c057aa39ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Fri, 7 Jul 2023 12:17:10 +0200 Subject: [PATCH 04/16] fix(jdbc): DateTimeFormatter can be reused in the JdbcMapper --- core/src/test/resources/flows/valids/execution.yaml | 6 ++++++ jdbc/src/main/java/io/kestra/jdbc/JdbcMapper.java | 12 +++++------- .../java/io/kestra/jdbc/runner/JdbcRunnerTest.java | 8 ++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 core/src/test/resources/flows/valids/execution.yaml diff --git a/core/src/test/resources/flows/valids/execution.yaml b/core/src/test/resources/flows/valids/execution.yaml new file mode 100644 index 00000000000..401e4cfceee --- /dev/null +++ b/core/src/test/resources/flows/valids/execution.yaml @@ -0,0 +1,6 @@ +id: execution-start-date +namespace: io.kestra.tests +tasks: + - id: hello + type: io.kestra.core.tasks.debugs.Return + format: "{{ execution.startDate }}" \ No newline at end of file diff --git a/jdbc/src/main/java/io/kestra/jdbc/JdbcMapper.java b/jdbc/src/main/java/io/kestra/jdbc/JdbcMapper.java index fd149addb4b..339b01954c3 100644 --- a/jdbc/src/main/java/io/kestra/jdbc/JdbcMapper.java +++ b/jdbc/src/main/java/io/kestra/jdbc/JdbcMapper.java @@ -14,6 +14,9 @@ import java.time.format.DateTimeFormatter; public abstract class JdbcMapper { + private static final DateTimeFormatter INSTANT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .withZone(ZoneOffset.UTC); + private static final DateTimeFormatter ZONED_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); private static ObjectMapper MAPPER; public static ObjectMapper of() { @@ -24,19 +27,14 @@ public static ObjectMapper of() { module.addSerializer(Instant.class, new JsonSerializer<>() { @Override public void serialize(Instant instant, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .withZone(ZoneOffset.UTC) - .format(instant) - ); + jsonGenerator.writeString(INSTANT_FORMATTER.format(instant)); } }); module.addSerializer(ZonedDateTime.class, new JsonSerializer<>() { @Override public void serialize(ZonedDateTime instant, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX") - .format(instant) - ); + jsonGenerator.writeString(ZONED_DATE_TIME_FORMATTER.format(instant)); } }); diff --git a/jdbc/src/test/java/io/kestra/jdbc/runner/JdbcRunnerTest.java b/jdbc/src/test/java/io/kestra/jdbc/runner/JdbcRunnerTest.java index ba2253d3fbd..9b301a1111a 100644 --- a/jdbc/src/test/java/io/kestra/jdbc/runner/JdbcRunnerTest.java +++ b/jdbc/src/test/java/io/kestra/jdbc/runner/JdbcRunnerTest.java @@ -28,6 +28,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.matchesPattern; @MicronautTest(transactional = false) @TestInstance(TestInstance.Lifecycle.PER_CLASS) // must be per-class to allow calling once init() which took a lot of time @@ -241,4 +242,11 @@ public void pauseRunDelay() throws Exception { public void pauseRunTimeout() throws Exception { pauseTest.runTimeout(runnerUtils); } + + @Test + void executionDate() throws TimeoutException { + Execution execution = runnerUtils.runOne("io.kestra.tests", "execution-start-date", null, null, Duration.ofSeconds(60)); + + assertThat((String) execution.getTaskRunList().get(0).getOutputs().get("value"), matchesPattern("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z")); + } } From e7e200e3849445b97c7b5f9ca15eea36631f42b4 Mon Sep 17 00:00:00 2001 From: Anna Geller Date: Tue, 11 Jul 2023 09:50:03 +0200 Subject: [PATCH 05/16] docs fix wdir and API (#1730) --- .../io/kestra/core/tasks/flows/WorkingDirectory.java | 11 +++++++---- ui/src/translations.json | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/io/kestra/core/tasks/flows/WorkingDirectory.java b/core/src/main/java/io/kestra/core/tasks/flows/WorkingDirectory.java index d233396c9b9..654fd76dd56 100644 --- a/core/src/main/java/io/kestra/core/tasks/flows/WorkingDirectory.java +++ b/core/src/main/java/io/kestra/core/tasks/flows/WorkingDirectory.java @@ -29,10 +29,13 @@ @Getter @NoArgsConstructor @Schema( - title = "Run tasks sequentially sharing the same working directory", - description = "By default, Kestra will launch each task on a fresh working directory and on a new worker instance.\n" + - "This task will run sequentially keeping the same filesystem allowing reuse of previous task files on next tasks and" + - "keeping track of execution time for each tasks. It can only runs runnable tasks as tasks will be run immediately on the worker" + title = "Run tasks sequentially in the same working directory", + description = "Tasks are stateless by default. Kestra will launch each task within a temporary working directory on a Worker.\n" + + "The `WorkingDirectory` task allows reusing the same file system's working directory across multiple tasks \n" + + "so that multiple sequential tasks can use output files from previous tasks without having to use the `{{outputs.taskId.outputName}}` syntax." + + "Note that the `WorkingDirectory` only works with runnable tasks because those tasks are executed directly on the Worker." + + "This means that using flowable tasks such as the `Parallel` task within the `WorkingDirectory` task will not work." + + "The `WorkingDirectory` task requires Kestra>=0.9.0." ) @Plugin( examples = { diff --git a/ui/src/translations.json b/ui/src/translations.json index ff07889c0ef..7e9b87d465f 100644 --- a/ui/src/translations.json +++ b/ui/src/translations.json @@ -451,7 +451,7 @@ } }, "title": "Title", - "api": "Api", + "api": "API", "expand error": "Expand only failed task", "expand all": "Expand all", "collapse all": "Collapse all", @@ -915,7 +915,7 @@ } }, "title": "Titre", - "api": "Api", + "api": "API", "expand error": "Afficher uniquement les erreurs", "expand all": "Afficher tout", "collapse all": "Masquer tout", From 38beef4919190cb240c2da03028c5b651d5f2baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Fri, 7 Jul 2023 15:57:01 +0200 Subject: [PATCH 06/16] fix(core): add worker group tag to the metrics --- .../kestra/core/metrics/MetricRegistry.java | 22 +++++++++++++-- .../java/io/kestra/core/runners/Worker.java | 28 +++++++++++-------- .../core/schedulers/AbstractScheduler.java | 1 - 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/io/kestra/core/metrics/MetricRegistry.java b/core/src/main/java/io/kestra/core/metrics/MetricRegistry.java index 2aadd2b1f89..5ce504f30d5 100644 --- a/core/src/main/java/io/kestra/core/metrics/MetricRegistry.java +++ b/core/src/main/java/io/kestra/core/metrics/MetricRegistry.java @@ -59,6 +59,7 @@ public class MetricRegistry { public final static String TAG_NAMESPACE_ID = "namespace_id"; public final static String TAG_STATE = "state"; public final static String TAG_ATTEMPT_COUNT = "attempt_count"; + public final static String TAG_WORKER_GROUP = "worker_group"; @Inject private MeterRegistry meterRegistry; @@ -128,10 +129,11 @@ private String metricName(String name) { * We don't include current state since it will breakup the values per state and it's make no sense. * * @param workerTask the current WorkerTask + * @param workerGroup the worker group, optional * @return tags to applied to metrics */ - public String[] tags(WorkerTask workerTask, String... tags) { - return ArrayUtils.addAll( + public String[] tags(WorkerTask workerTask, String workerGroup, String... tags) { + var finalTags = ArrayUtils.addAll( ArrayUtils.addAll( this.tags(workerTask.getTask()), tags @@ -139,6 +141,7 @@ public String[] tags(WorkerTask workerTask, String... tags) { TAG_NAMESPACE_ID, workerTask.getTaskRun().getNamespace(), TAG_FLOW_ID, workerTask.getTaskRun().getFlowId() ); + return workerGroup != null ? ArrayUtils.addAll(finalTags, TAG_WORKER_GROUP, workerGroup) : finalTags; } /** @@ -182,6 +185,21 @@ public String[] tags(Execution execution) { }; } + /** + * Return tags for current {@link TriggerContext} + * + * @param triggerContext the current TriggerContext + * @param workerGroup the worker group, optional + * @return tags to applied to metrics + */ + public String[] tags(TriggerContext triggerContext, String workerGroup) { + var finalTags = new String[]{ + TAG_FLOW_ID, triggerContext.getFlowId(), + TAG_NAMESPACE_ID, triggerContext.getNamespace() + }; + return workerGroup != null ? ArrayUtils.addAll(finalTags, TAG_WORKER_GROUP, workerGroup) : finalTags; + } + /** * Return tags for current {@link TriggerContext} * diff --git a/core/src/main/java/io/kestra/core/runners/Worker.java b/core/src/main/java/io/kestra/core/runners/Worker.java index fbc94b7371b..e8bbe025900 100644 --- a/core/src/main/java/io/kestra/core/runners/Worker.java +++ b/core/src/main/java/io/kestra/core/runners/Worker.java @@ -170,10 +170,10 @@ private void handleTask(WorkerTask workerTask) { private void handleTrigger(WorkerTrigger workerTrigger) { this.metricRegistry - .timer(MetricRegistry.METRIC_WORKER_EVALUATE_TRIGGER_DURATION, metricRegistry.tags(workerTrigger.getTriggerContext())) + .timer(MetricRegistry.METRIC_WORKER_EVALUATE_TRIGGER_DURATION, metricRegistry.tags(workerTrigger.getTriggerContext(), workerGroup)) .record(() -> { this.evaluateTriggerRunningCount.computeIfAbsent(workerTrigger.getTriggerContext().uid(), s -> metricRegistry - .gauge(MetricRegistry.METRIC_WORKER_EVALUATE_TRIGGER_RUNNING_COUNT, new AtomicInteger(0), metricRegistry.tags(workerTrigger.getTriggerContext()))); + .gauge(MetricRegistry.METRIC_WORKER_EVALUATE_TRIGGER_RUNNING_COUNT, new AtomicInteger(0), metricRegistry.tags(workerTrigger.getTriggerContext(), workerGroup))); this.evaluateTriggerRunningCount.get(workerTrigger.getTriggerContext().uid()).addAndGet(1); try { @@ -248,12 +248,12 @@ private WorkerTask cleanUpTransient(WorkerTask workerTask) { private WorkerTaskResult run(WorkerTask workerTask, Boolean cleanUp) throws QueueException { metricRegistry - .counter(MetricRegistry.METRIC_WORKER_STARTED_COUNT, metricRegistry.tags(workerTask)) + .counter(MetricRegistry.METRIC_WORKER_STARTED_COUNT, metricRegistry.tags(workerTask, workerGroup)) .increment(); if (workerTask.getTaskRun().getState().getCurrent() == State.Type.CREATED) { metricRegistry - .timer(MetricRegistry.METRIC_WORKER_QUEUED_DURATION, metricRegistry.tags(workerTask)) + .timer(MetricRegistry.METRIC_WORKER_QUEUED_DURATION, metricRegistry.tags(workerTask, workerGroup)) .record(Duration.between( workerTask.getTaskRun().getState().getStartDate(), now() )); @@ -315,7 +315,8 @@ private WorkerTaskResult run(WorkerTask workerTask, Boolean cleanUp) throws Queu MetricRegistry.METRIC_WORKER_RETRYED_COUNT, metricRegistry.tags( current.get(), - MetricRegistry.TAG_ATTEMPT_COUNT, String.valueOf(e.getAttemptCount()) + MetricRegistry.TAG_ATTEMPT_COUNT, String.valueOf(e.getAttemptCount()), + MetricRegistry.TAG_WORKER_GROUP, workerGroup ) ) .increment(); @@ -380,11 +381,11 @@ private WorkerTaskResult run(WorkerTask workerTask, Boolean cleanUp) throws Queu private void logTerminated(WorkerTask workerTask) { metricRegistry - .counter(MetricRegistry.METRIC_WORKER_ENDED_COUNT, metricRegistry.tags(workerTask)) + .counter(MetricRegistry.METRIC_WORKER_ENDED_COUNT, metricRegistry.tags(workerTask, workerGroup)) .increment(); metricRegistry - .timer(MetricRegistry.METRIC_WORKER_ENDED_DURATION, metricRegistry.tags(workerTask)) + .timer(MetricRegistry.METRIC_WORKER_ENDED_DURATION, metricRegistry.tags(workerTask, workerGroup)) .record(workerTask.getTaskRun().getState().getDuration()); workerTask.logger().info( @@ -445,7 +446,7 @@ private WorkerTask runAttempt(WorkerTask workerTask) { metricRunningCount.incrementAndGet(); - WorkerThread workerThread = new WorkerThread(logger, workerTask, task, runContext, metricRegistry); + WorkerThread workerThread = new WorkerThread(logger, workerTask, task, runContext, metricRegistry, workerGroup); // emit attempts this.workerTaskResultQueue.emit(new WorkerTaskResult(workerTask @@ -516,7 +517,7 @@ private List addAttempt(WorkerTask workerTask, TaskRunAttempt ta } public AtomicInteger getMetricRunningCount(WorkerTask workerTask) { - String[] tags = this.metricRegistry.tags(workerTask); + String[] tags = this.metricRegistry.tags(workerTask, workerGroup); Arrays.sort(tags); long index = Hashing @@ -528,7 +529,7 @@ public AtomicInteger getMetricRunningCount(WorkerTask workerTask) { .computeIfAbsent(index, l -> metricRegistry.gauge( MetricRegistry.METRIC_WORKER_RUNNING_COUNT, new AtomicInteger(0), - metricRegistry.tags(workerTask) + metricRegistry.tags(workerTask, workerGroup) )); } @@ -591,12 +592,13 @@ public static class WorkerThread extends Thread { RunnableTask task; RunContext runContext; MetricRegistry metricRegistry; + String workerGroup; Output taskOutput; io.kestra.core.models.flows.State.Type taskState; boolean killed = false; - public WorkerThread(Logger logger, WorkerTask workerTask, RunnableTask task, RunContext runContext, MetricRegistry metricRegistry) { + public WorkerThread(Logger logger, WorkerTask workerTask, RunnableTask task, RunContext runContext, MetricRegistry metricRegistry, String workerGroup) { super("WorkerThread"); this.setUncaughtExceptionHandler(this::exceptionHandler); @@ -605,6 +607,7 @@ public WorkerThread(Logger logger, WorkerTask workerTask, RunnableTask task, this.task = task; this.runContext = runContext; this.metricRegistry = metricRegistry; + this.workerGroup = workerGroup; } @Override @@ -623,7 +626,8 @@ public void run() { MetricRegistry.METRIC_WORKER_TIMEOUT_COUNT, metricRegistry.tags( this.workerTask, - MetricRegistry.TAG_ATTEMPT_COUNT, String.valueOf(event.getAttemptCount()) + MetricRegistry.TAG_ATTEMPT_COUNT, String.valueOf(event.getAttemptCount()), + MetricRegistry.TAG_WORKER_GROUP, workerGroup ) ) .increment() diff --git a/core/src/main/java/io/kestra/core/schedulers/AbstractScheduler.java b/core/src/main/java/io/kestra/core/schedulers/AbstractScheduler.java index c653fd8b6a9..2046c1c07ea 100644 --- a/core/src/main/java/io/kestra/core/schedulers/AbstractScheduler.java +++ b/core/src/main/java/io/kestra/core/schedulers/AbstractScheduler.java @@ -39,7 +39,6 @@ import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.*; -import java.util.stream.Collectors; import java.util.stream.Stream; import jakarta.inject.Inject; import jakarta.inject.Singleton; From 4262ab58944d45f96975c7e9fa20a65ee4243bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Mon, 10 Jul 2023 10:03:34 +0200 Subject: [PATCH 07/16] fix(core): make the RetryTest more resilient --- core/src/test/java/io/kestra/core/runners/RetryTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/src/test/java/io/kestra/core/runners/RetryTest.java b/core/src/test/java/io/kestra/core/runners/RetryTest.java index 12de5f8005b..de5b7f6a289 100644 --- a/core/src/test/java/io/kestra/core/runners/RetryTest.java +++ b/core/src/test/java/io/kestra/core/runners/RetryTest.java @@ -38,10 +38,6 @@ void retryFailed() throws TimeoutException { assertThat(execution.getTaskRunList(), hasSize(2)); assertThat(execution.getTaskRunList().get(0).getAttempts(), hasSize(5)); - - // be sure attempts are available on the queue - // we cannot know the exact number of executions, but we should have at least 15 of them - assertThat(executions.size(), greaterThan(15)); - assertThat(executions.get(8).getTaskRunList().get(0).getAttempts().size(), is(3)); + assertThat(execution.getState().getCurrent(), is(State.Type.FAILED)); } } From 16ac5151941d67b611f36080e75c7fe5f616eb81 Mon Sep 17 00:00:00 2001 From: YannC <37600690+Skraye@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:48:34 +0200 Subject: [PATCH 08/16] fix(core): Fix flow comparison method (#1740) --- .../main/java/io/kestra/core/models/flows/FlowWithSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/kestra/core/models/flows/FlowWithSource.java b/core/src/main/java/io/kestra/core/models/flows/FlowWithSource.java index 727f9282be1..6c950f01c48 100644 --- a/core/src/main/java/io/kestra/core/models/flows/FlowWithSource.java +++ b/core/src/main/java/io/kestra/core/models/flows/FlowWithSource.java @@ -55,7 +55,7 @@ private static String cleanupSource(String source) { } public boolean isUpdatable(Flow flow, String flowSource) { - return flow.equalsWithoutRevision(flow) && + return this.equalsWithoutRevision(flow) && this.source.equals(cleanupSource(flowSource)); } From 007142cf76bed3e60bc72bb7005da4a2ed813252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Thu, 13 Jul 2023 13:49:56 +0200 Subject: [PATCH 09/16] fix(core,webserver): store labels as a list instead of a map --- .../java/io/kestra/core/models/Label.java | 3 ++ .../core/models/executions/Execution.java | 9 +++- .../io/kestra/core/models/flows/Flow.java | 9 +++- .../io/kestra/core/runners/RunnerUtils.java | 13 +++--- .../java/io/kestra/core/runners/Worker.java | 5 ++- .../ListOrMapOfLabelDeserializer.java | 41 +++++++++++++++++++ .../ListOrMapOfLabelSerializer.java | 31 ++++++++++++++ .../java/io/kestra/core/tasks/flows/Flow.java | 7 +++- .../core/models/executions/ExecutionTest.java | 6 ++- .../core/models/triggers/types/FlowTest.java | 12 +++--- .../models/triggers/types/ScheduleTest.java | 11 ++--- .../schedulers/AbstractSchedulerTest.java | 7 ++-- .../core/schedulers/SchedulerThreadTest.java | 5 ++- .../h2/H2ExecutionRepositoryService.java | 8 ++-- .../io/kestra/runner/h2/H2FunctionsTest.java | 8 ++++ .../MysqlExecutionRepositoryService.java | 8 ++-- .../PostgresExecutionRepositoryService.java | 9 +--- ui/src/components/layout/Labels.vue | 18 +++++++- .../controllers/ExecutionController.java | 16 +++++++- .../controllers/ExecutionControllerTest.java | 14 ++++--- 20 files changed, 190 insertions(+), 50 deletions(-) create mode 100644 core/src/main/java/io/kestra/core/models/Label.java create mode 100644 core/src/main/java/io/kestra/core/serializers/ListOrMapOfLabelDeserializer.java create mode 100644 core/src/main/java/io/kestra/core/serializers/ListOrMapOfLabelSerializer.java diff --git a/core/src/main/java/io/kestra/core/models/Label.java b/core/src/main/java/io/kestra/core/models/Label.java new file mode 100644 index 00000000000..290c2631da1 --- /dev/null +++ b/core/src/main/java/io/kestra/core/models/Label.java @@ -0,0 +1,3 @@ +package io.kestra.core.models; + +public record Label(String key, String value) {} diff --git a/core/src/main/java/io/kestra/core/models/executions/Execution.java b/core/src/main/java/io/kestra/core/models/executions/Execution.java index f1a933a55ca..caa744509f9 100644 --- a/core/src/main/java/io/kestra/core/models/executions/Execution.java +++ b/core/src/main/java/io/kestra/core/models/executions/Execution.java @@ -5,8 +5,13 @@ import ch.qos.logback.classic.spi.ThrowableProxy; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Streams; +import io.kestra.core.models.Label; +import io.kestra.core.serializers.ListOrMapOfLabelDeserializer; +import io.kestra.core.serializers.ListOrMapOfLabelSerializer; import lombok.Builder; import lombok.Value; import lombok.With; @@ -53,7 +58,9 @@ public class Execution implements DeletedInterface { Map inputs; @With - Map labels; + @JsonSerialize(using = ListOrMapOfLabelSerializer.class) + @JsonDeserialize(using = ListOrMapOfLabelDeserializer.class) + List