Skip to content

Commit

Permalink
fix(core): serialize duration as strings
Browse files Browse the repository at this point in the history
Fixes #5615

Since Jackson 2.10, to serialize duration as string we need to switch WRITE_DURATIONS_AS_TIMESTAMPS off as it no longuer use WRITE_DATES_AS_TIMESTAMPS.
I tested and an old flow with a duration as timestamp is still readable so this is a backward compatible change.

But for the State duration, we still need to serialize it as a number as the database expect a number
  • Loading branch information
loicmathieu committed Oct 28, 2024
1 parent c20e105 commit 63d70ac
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 3 deletions.
7 changes: 6 additions & 1 deletion core/src/main/java/io/kestra/core/models/flows/State.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package io.kestra.core.models.flows;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.DurationSerializer;
import com.fasterxml.jackson.datatype.jsr310.util.DurationUnitConverter;
import io.micronaut.core.annotation.Introspected;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -84,10 +88,11 @@ public State reset() {
}

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@JsonFormat(shape = JsonFormat.Shape.NUMBER_INT) // force serialization as timestamp as the database column is using a number
public Duration getDuration() {
return Duration.between(
this.histories.getFirst().getDate(),
this.histories.size() > 1 ? this.histories.get(this.histories.size() - 1).getDate() : Instant.now()
this.histories.size() > 1 ? this.histories.getLast().getDate() : Instant.now()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public static ObjectMapper ofIon() {
private static ObjectMapper configure(ObjectMapper mapper) {
return mapper
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.registerModule(new JavaTimeModule())
.registerModule(new Jdk8Module())
Expand Down
3 changes: 1 addition & 2 deletions core/src/test/java/io/kestra/plugin/core/kv/SetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,7 @@ void typeSpecified() throws Exception {
assertThat(kv.getValue(TEST_KEY).get().value(), is(Instant.parse("2023-05-02T01:02:03Z")));

set.toBuilder().value("P1DT5S").kvType(KVType.DURATION).build().run(runContext);
// TODO Hack meanwhile we handle duration serialization as currently they are stored as bigint...
assertThat((long) Double.parseDouble(kv.getValue(TEST_KEY).get().value().toString()), is(Duration.ofDays(1).plus(Duration.ofSeconds(5)).toSeconds()));
assertThat(kv.getValue(TEST_KEY).get().value(), is(Duration.ofDays(1).plus(Duration.ofSeconds(5))));

set.toBuilder().value("[{\"some\":\"value\"},{\"another\":\"value\"}]").kvType(KVType.JSON).build().run(runContext);
assertThat(kv.getValue(TEST_KEY).get().value(), is(List.of(Map.of("some", "value"), Map.of("another", "value"))));
Expand Down

0 comments on commit 63d70ac

Please sign in to comment.