From 7e0a8f21382b04d94bc55b8c1fd20ae324d9c1bc Mon Sep 17 00:00:00 2001 From: bogdandina Date: Thu, 4 Dec 2025 00:13:36 +0200 Subject: [PATCH 1/9] feat(70552): upgrade to Java 25 --- pom.xml | 105 ++++-------------- .../java/fi/hsl/common/hfp/HfpParser.java | 3 +- .../passengercount/PassengerCountParser.java | 6 +- 3 files changed, 25 insertions(+), 89 deletions(-) diff --git a/pom.xml b/pom.xml index f31b37ee..351259c5 100644 --- a/pom.xml +++ b/pom.xml @@ -2,44 +2,35 @@ 4.0.0 fi.hsl transitdata-common - 2.0.5 + 3.0.1 jar Common utilities for Transitdata projects + UTF-8 - 11 - 11 + 25 3.0.7 1.18.3 2.43.0 - 1.17.0 + 1.23.0 - unit-test true - unit-test true false - + integration-test - integration-test false true @@ -61,82 +52,67 @@ protobuf-java 3.21.12 - com.dslplatform - dsl-json-java8 + dsl-json 1.10.0 - org.apache.pulsar pulsar-client ${pulsar.version} - org.apache.pulsar pulsar-client-admin ${pulsar.version} - redis.clients jedis 4.4.3 - jar - compile - com.typesafe config 1.4.2 - ch.qos.logback logback-classic 1.4.7 - ch.qos.logback.contrib logback-json-classic 0.1.5 - ch.qos.logback.contrib logback-jackson 0.1.5 - org.slf4j slf4j-api 2.0.7 - com.fasterxml.jackson.core jackson-databind 2.15.0 - org.jetbrains annotations 24.0.1 - junit junit 4.13.2 test - org.testcontainers testcontainers @@ -149,17 +125,16 @@ ${testcontainers.version} test - ${project.artifactId}-${project.version} + src/main/resources true - logback.xml @@ -167,6 +142,15 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 25 + + + org.apache.maven.plugins maven-assembly-plugin @@ -188,36 +172,7 @@ - - org.apache.maven.plugins - maven-compiler-plugin - 3.11.0 - - 11 - 11 - - - - com.coderplus.maven.plugins - copy-rename-maven-plugin - 1.0.1 - - - copy-and-rename-pom-file - package - - copy - - - ${project.basedir}/pom.xml - ${project.build.directory}/${project.build.finalName}.pom - - - - - - org.apache.maven.plugins maven-jar-plugin @@ -229,31 +184,12 @@ - - org.apache.maven.plugins - maven-assembly-plugin - - - test-jar-with-dependencies.xml - - - - - - - - single - - - - org.codehaus.mojo build-helper-maven-plugin 3.4.0 - add-integration-test-sources generate-test-sources @@ -261,13 +197,11 @@ add-test-source - src/integration-test/java - add-integration-test-resources generate-test-resources @@ -277,13 +211,12 @@ - true src/integration-test/resources + true - @@ -293,7 +226,6 @@ 3.1.2 ${skip.unit.tests} - **/IT*.java @@ -306,6 +238,7 @@ + org.apache.maven.plugins maven-failsafe-plugin @@ -323,6 +256,7 @@ + com.diffplug.spotless spotless-maven-plugin @@ -349,6 +283,7 @@ + diff --git a/src/main/java/fi/hsl/common/hfp/HfpParser.java b/src/main/java/fi/hsl/common/hfp/HfpParser.java index 1a262229..7967fffc 100644 --- a/src/main/java/fi/hsl/common/hfp/HfpParser.java +++ b/src/main/java/fi/hsl/common/hfp/HfpParser.java @@ -2,7 +2,6 @@ import com.dslplatform.json.DslJson; import com.dslplatform.json.ParsingException; -import com.dslplatform.json.runtime.Settings; import fi.hsl.common.hfp.proto.Hfp; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +34,7 @@ public class HfpParser { //Example: https://github.com/ngs-doo/dsl-json/blob/master/examples/MavenJava8/src/main/java/com/dslplatform/maven/Example.java //Note! Apparently not thread safe, for per thread reuse use ThreadLocal pattern or create separate instances - final DslJson dslJson = new DslJson<>(Settings.withRuntime().allowArrayFormat(true).includeServiceLoader()); + final DslJson dslJson = new DslJson<>(new DslJson.Settings<>().allowArrayFormat(true).includeServiceLoader()); private static void foundVehicleWithEmptyTransportMode(String uniqueVehicleId) { vehiclesWithEmptyTransportMode.add(uniqueVehicleId); diff --git a/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java b/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java index e4d80045..719ffa01 100644 --- a/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java +++ b/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java @@ -2,7 +2,6 @@ import com.dslplatform.json.DslJson; import com.dslplatform.json.ParsingException; -import com.dslplatform.json.runtime.Settings; import fi.hsl.common.passengercount.json.*; import fi.hsl.common.passengercount.proto.PassengerCount; import org.jetbrains.annotations.NotNull; @@ -20,7 +19,10 @@ public class PassengerCountParser { static final Pattern topicVersionRegex = Pattern.compile("(^v\\d+|dev)"); - final DslJson dslJson = new DslJson<>(Settings.withRuntime().allowArrayFormat(true).includeServiceLoader()); + DslJson dslJson = new DslJson<>( + new DslJson.Settings<>() + .allowArrayFormat(true) + .includeServiceLoader()); @NotNull public static PassengerCountParser newInstance() { From d141d75f573b7e96c719f5e4dfb326927bdb3dcc Mon Sep 17 00:00:00 2001 From: bogdandina Date: Thu, 4 Dec 2025 09:42:25 +0200 Subject: [PATCH 2/9] feat(70552): change to Java 25 in Github Actions Workflow --- .github/workflows/test-and-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-and-build.yml b/.github/workflows/test-and-build.yml index 40781059..af7c7d0b 100644 --- a/.github/workflows/test-and-build.yml +++ b/.github/workflows/test-and-build.yml @@ -7,11 +7,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 25 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: '11' + java-version: '25' cache: 'maven' - name: Run Spotless Apply run: mvn spotless:apply @@ -28,11 +28,11 @@ jobs: if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 25 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: '11' + java-version: '25' cache: 'maven' - name: Publish package run: mvn --batch-mode deploy From 27bf34ab792d919bb77e12ae3ed03412d4ad016a Mon Sep 17 00:00:00 2001 From: bogdandina Date: Thu, 4 Dec 2025 10:31:45 +0200 Subject: [PATCH 3/9] feat(70552): potential fix --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 351259c5..f2cf30bc 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ com.dslplatform dsl-json - 1.10.0 + 2.0.2 org.apache.pulsar From 4363e2b1c9dc788b14f34ae50708daf935f64243 Mon Sep 17 00:00:00 2001 From: bogdandina Date: Sat, 6 Dec 2025 16:53:42 +0200 Subject: [PATCH 4/9] feat(70552): refactoring to Jackson from DSLJson --- pom.xml | 22 ++++- src/main/java/fi/hsl/common/hfp/HfpJson.java | 93 +++++++++++-------- .../java/fi/hsl/common/hfp/HfpParser.java | 58 ++++++------ .../passengercount/PassengerCountParser.java | 29 +++--- .../hsl/common/passengercount/json/Apc.java | 8 +- .../common/passengercount/json/ApcJson.java | 10 +- .../hsl/common/passengercount/json/Count.java | 8 +- .../common/passengercount/json/DoorCount.java | 4 +- .../passengercount/json/Vehiclecounts.java | 5 +- 9 files changed, 140 insertions(+), 97 deletions(-) diff --git a/pom.xml b/pom.xml index f2cf30bc..31e32bc2 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ 1.18.3 2.43.0 1.23.0 + 2.20.1 @@ -53,9 +54,24 @@ 3.21.12 - com.dslplatform - dsl-json - 2.0.2 + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + 2.20 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} org.apache.pulsar diff --git a/src/main/java/fi/hsl/common/hfp/HfpJson.java b/src/main/java/fi/hsl/common/hfp/HfpJson.java index cbeff088..afa8c043 100644 --- a/src/main/java/fi/hsl/common/hfp/HfpJson.java +++ b/src/main/java/fi/hsl/common/hfp/HfpJson.java @@ -1,22 +1,33 @@ package fi.hsl.common.hfp; -import com.dslplatform.json.*; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.io.IOException; -// ignore unknown properties (default for objects). -// to disallow unknown properties in JSON set it to FAIL which will result in exception instead -@CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) +@JsonIgnoreProperties(ignoreUnknown = true) public class HfpJson { //Specification: https://digitransit.fi/en/developers/apis/4-realtime-api/vehicle-positions/ //Example payload: // {"VP":{"desi":"81","dir":"2","oper":22,"veh":792,"tst":"2018-04-05T17:38:36Z","tsi":1522949916,"spd":0.16,"hdg":225,"lat":60.194481,"long":25.03095,"acc":0,"dl":-25,"odo":2819,"drst":0,"oday":"2018-04-05","jrn":636,"line":112,"start":"20:25"}} - @JsonAttribute(nullable = false, name = "VP", alternativeNames = {"DUE", "ARR", "DEP", "ARS", "PDE", "PAS", "WAIT", - "DOO", "DOC", "TLR", "TLA", "DA", "DOUT", "BA", "BOUT", "VJA", "VJOUT"}) + @JsonProperty("VP") + @JsonAlias({"DUE", "ARR", "DEP", "ARS", "PDE", "PAS", "WAIT", + "DOO", "DOC", "TLR", "TLA", "DA", "DOUT", "BA", "BOUT", + "VJA", "VJOUT"}) public Payload payload; - @CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) + @JsonIgnoreProperties(ignoreUnknown = true) public static class Payload { public String desi; @@ -27,10 +38,10 @@ public static class Payload { public Integer veh; - @JsonAttribute(nullable = false) + @JsonProperty(required = true) public String tst; - @JsonAttribute(nullable = false) + @JsonProperty(required = true) public long tsi; public Double spd; @@ -39,14 +50,15 @@ public static class Payload { public Double lat; - @JsonAttribute(name = "long") //use alternative name in JSON + @JsonProperty("long") //use alternative name in JSON public Double longitude; public Double acc; public Integer dl; - @JsonAttribute(converter = Odo.class) + @JsonDeserialize(using = OdoDeserializer.class) + @JsonSerialize(using = OdoSerializer.class) public Double odo; public Integer drst; @@ -73,65 +85,70 @@ public static class Payload { public String ttdep; - @JsonAttribute(name = "dr-type") //use alternative name in JSON + @JsonProperty("dr-type") //use alternative name in JSON public Integer dr_type; - @JsonAttribute(name = "tlp-requestid") //use alternative name in JSON + @JsonProperty("tlp-requestid") public Integer tlp_requestid; - @JsonAttribute(name = "tlp-requesttype") //use alternative name in JSON + @JsonProperty("tlp-requesttype") public String tlp_requesttype; - @JsonAttribute(name = "tlp-prioritylevel") //use alternative name in JSON + @JsonProperty("tlp-prioritylevel") public String tlp_prioritylevel; - @JsonAttribute(name = "tlp-reason") //use alternative name in JSON + @JsonProperty("tlp-reason") public String tlp_reason; - @JsonAttribute(name = "tlp-att-seq") //use alternative name in JSON + @JsonProperty("tlp-att-seq") public Integer tlp_att_seq; - @JsonAttribute(name = "tlp-decision") //use alternative name in JSON + @JsonProperty("tlp-decision") public String tlp_decision; public Integer sid; - @JsonAttribute(name = "signal-groupid") //use alternative name in JSON + @JsonProperty("signal-groupid") public Integer signal_groupid; - @JsonAttribute(name = "tlp-signalgroupnbr") //use alternative name in JSON + @JsonProperty("tlp-signalgroupnbr") public Integer tlp_signalgroupnbr; - @JsonAttribute(name = "tlp-line-configid") //use alternative name in JSON + @JsonProperty("tlp-line-configid") public Integer tlp_line_configid; - @JsonAttribute(name = "tlp-point-configid") //use alternative name in JSON + @JsonProperty("tlp-point-configid") public Integer tlp_point_configid; - @JsonAttribute(name = "tlp-frequency") //use alternative name in JSON + @JsonProperty("tlp-frequency") public Integer tlp_frequency; - @JsonAttribute(name = "tlp-protocol") //use alternative name in JSON + @JsonProperty("tlp-protocol") public String tlp_protocol; public String label; } - public static abstract class Odo { - public static final JsonReader.ReadObject JSON_READER = new JsonReader.ReadObject() { - public Double read(JsonReader reader) throws IOException { - return reader.wasNull() ? null : NumberConverter.deserializeDouble(reader); + public static class OdoDeserializer extends JsonDeserializer { + @Override + public Double deserialize(JsonParser p, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + if (p.currentToken().isNumeric()) { + return p.getDoubleValue(); } - }; - - public static final JsonWriter.WriteObject JSON_WRITER = new JsonWriter.WriteObject() { - public void write(JsonWriter writer, Double value) { - if (value == null) - writer.writeNull(); - else - NumberConverter.serializeNullable(value.intValue(), writer); - } - }; + return null; + } } + public static class OdoSerializer extends JsonSerializer { + @Override + public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + if (value == null) { + gen.writeNull(); + } else { + gen.writeNumber(value.intValue()); + } + } + } } diff --git a/src/main/java/fi/hsl/common/hfp/HfpParser.java b/src/main/java/fi/hsl/common/hfp/HfpParser.java index 7967fffc..b7c9e3da 100644 --- a/src/main/java/fi/hsl/common/hfp/HfpParser.java +++ b/src/main/java/fi/hsl/common/hfp/HfpParser.java @@ -1,14 +1,15 @@ package fi.hsl.common.hfp; -import com.dslplatform.json.DslJson; -import com.dslplatform.json.ParsingException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import fi.hsl.common.hfp.proto.Hfp; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.validation.constraints.Null; import java.io.IOException; import java.sql.Date; import java.sql.Time; @@ -28,13 +29,11 @@ public class HfpParser { private static Set vehiclesWithEmptyTransportMode = new HashSet<>(); - // Let's use dsl-json (https://github.com/ngs-doo/dsl-json) for performance. - // Based on this benchmark: https://github.com/fabienrenaud/java-json-benchmark - - //Example: https://github.com/ngs-doo/dsl-json/blob/master/examples/MavenJava8/src/main/java/com/dslplatform/maven/Example.java - - //Note! Apparently not thread safe, for per thread reuse use ThreadLocal pattern or create separate instances - final DslJson dslJson = new DslJson<>(new DslJson.Settings<>().allowArrayFormat(true).includeServiceLoader()); + final ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true) + .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); private static void foundVehicleWithEmptyTransportMode(String uniqueVehicleId) { vehiclesWithEmptyTransportMode.add(uniqueVehicleId); @@ -53,32 +52,35 @@ public static HfpParser newInstance() { /** * Methods for parsing the Json Payload **/ - @Nullable public HfpJson parseJson(@NotNull byte[] data) throws IOException, InvalidHfpPayloadException { try { - return dslJson.deserialize(HfpJson.class, data, data.length); + HfpJson hfpJson = objectMapper.readValue(data, HfpJson.class); + validateRequiredFields(hfpJson); + return hfpJson; } catch (IOException ioe) { - if (ioe instanceof ParsingException) { - throw new InvalidHfpPayloadException("Failed to parse HFP JSON", (ParsingException) ioe); - } else { - throw ioe; - } + throw new InvalidHfpPayloadException("Failed to parse HFP JSON", ioe); + } + } + + private void validateRequiredFields(HfpJson hfpJson) throws InvalidHfpPayloadException { + if (hfpJson == null || hfpJson.payload == null) { + throw new InvalidHfpPayloadException("Payload is missing or null"); + } + HfpJson.Payload p = hfpJson.payload; + if (p.tst == null) { + throw new InvalidHfpPayloadException("Field 'tst' cannot be null"); } } @NotNull public String serializeToString(@NotNull final HfpJson json) throws IOException { - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - dslJson.serialize(json, os); - return os.toString("UTF-8"); + return objectMapper.writeValueAsString(json); } @NotNull public byte[] serializeToByteArray(@NotNull final HfpJson json) throws IOException { - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - dslJson.serialize(json, os); - return os.toByteArray(); + return objectMapper.writeValueAsBytes(json); } public Optional safeParse(@NotNull byte[] data) { @@ -96,12 +98,11 @@ public static Hfp.Payload parsePayload(@NotNull HfpJson json) { final HfpJson.Payload payload = json.payload; Hfp.Payload.Builder builder = Hfp.Payload.newBuilder(); - // Required attributes + builder.setSchemaVersion(builder.getSchemaVersion()); HfpValidator.validateString(payload.tst).ifPresent(builder::setTst); // TODO add validation for offsetdatetime format builder.setTsi(payload.tsi); - // Optional attributes HfpValidator.validateString(payload.desi).ifPresent(builder::setDesi); HfpValidator.validateString(payload.dir).ifPresent(builder::setDir); if (payload.oper != null) @@ -173,7 +174,6 @@ public static Hfp.Payload parsePayload(@NotNull HfpJson json) { /** * Methods for parsing the data from the topic */ - public static Optional safeParseTopic(@NotNull String topic) { try { return Optional.of(parseTopic(topic)); @@ -440,7 +440,11 @@ private InvalidHfpTopicException(String message) { } public static class InvalidHfpPayloadException extends Exception { - private InvalidHfpPayloadException(String message, ParsingException cause) { + public InvalidHfpPayloadException(String message) { + super(message); + } + + public InvalidHfpPayloadException(String message, Throwable cause) { super(message, cause); } } diff --git a/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java b/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java index 719ffa01..00a307e1 100644 --- a/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java +++ b/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java @@ -1,7 +1,9 @@ package fi.hsl.common.passengercount; -import com.dslplatform.json.DslJson; -import com.dslplatform.json.ParsingException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import fi.hsl.common.passengercount.json.*; import fi.hsl.common.passengercount.proto.PassengerCount; import org.jetbrains.annotations.NotNull; @@ -19,10 +21,11 @@ public class PassengerCountParser { static final Pattern topicVersionRegex = Pattern.compile("(^v\\d+|dev)"); - DslJson dslJson = new DslJson<>( - new DslJson.Settings<>() - .allowArrayFormat(true) - .includeServiceLoader()); + ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true) + .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); @NotNull public static PassengerCountParser newInstance() { @@ -261,23 +264,23 @@ public ApcJson toJson(PassengerCount.Payload passengerCountPayload) { } public OutputStream serializeJson(ApcJson apcJson, OutputStream outputStream) throws IOException { - dslJson.serialize(apcJson, outputStream); + objectMapper.writeValue(outputStream, apcJson); return outputStream; } @Nullable public ApcJson parseJson(byte @NotNull [] data) throws IOException, InvalidAPCPayloadException { try { - return dslJson.deserialize(ApcJson.class, data, data.length); + return objectMapper.readValue(data, ApcJson.class); } catch (IOException ioe) { - if (ioe instanceof ParsingException) { - throw new PassengerCountParser.InvalidAPCPayloadException("Failed to parse APC JSON", - (ParsingException) ioe); + if (ioe instanceof com.fasterxml.jackson.core.JsonProcessingException jpe) { + throw new PassengerCountParser.InvalidAPCPayloadException( + "Failed to parse APC JSON", jpe + ); } else { throw ioe; } } - } private static OptionalDouble safeParseDouble(String s) { @@ -336,7 +339,7 @@ private InvalidAPCTopicException(String message) { } public static class InvalidAPCPayloadException extends Exception { - private InvalidAPCPayloadException(String message, ParsingException cause) { + private InvalidAPCPayloadException(String message, JsonProcessingException cause) { super(message, cause); } } diff --git a/src/main/java/fi/hsl/common/passengercount/json/Apc.java b/src/main/java/fi/hsl/common/passengercount/json/Apc.java index 33ff2284..8ef28eb5 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/Apc.java +++ b/src/main/java/fi/hsl/common/passengercount/json/Apc.java @@ -1,11 +1,11 @@ package fi.hsl.common.passengercount.json; -import com.dslplatform.json.CompiledJson; -import com.dslplatform.json.JsonAttribute; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Date; -@CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) +@JsonIgnoreProperties public class Apc { public String desi; public String dir; @@ -14,7 +14,7 @@ public class Apc { public Date tst; public Long tsi; public Double lat; - @JsonAttribute(name = "long") + @JsonProperty("long") public Double lon; public Double odo; public String oday; diff --git a/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java b/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java index fa41c590..aa2b2cd5 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java +++ b/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java @@ -1,10 +1,12 @@ package fi.hsl.common.passengercount.json; -import com.dslplatform.json.CompiledJson; -import com.dslplatform.json.JsonAttribute; -@CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) public class ApcJson { - @JsonAttribute(nullable = false, name = "APC") + + @JsonProperty(value = "APC", required = true) public Apc apc; } diff --git a/src/main/java/fi/hsl/common/passengercount/json/Count.java b/src/main/java/fi/hsl/common/passengercount/json/Count.java index 70dcf943..b9c11a20 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/Count.java +++ b/src/main/java/fi/hsl/common/passengercount/json/Count.java @@ -1,12 +1,12 @@ package fi.hsl.common.passengercount.json; -import com.dslplatform.json.CompiledJson; -import com.dslplatform.json.JsonAttribute; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; -@CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) +@JsonIgnoreProperties(ignoreUnknown = true) public class Count { - @JsonAttribute(nullable = false, name = "class") + @JsonProperty(value = "class", required = true) public String clazz; public int in; public int out; diff --git a/src/main/java/fi/hsl/common/passengercount/json/DoorCount.java b/src/main/java/fi/hsl/common/passengercount/json/DoorCount.java index 633b8e33..bf0c39eb 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/DoorCount.java +++ b/src/main/java/fi/hsl/common/passengercount/json/DoorCount.java @@ -1,10 +1,10 @@ package fi.hsl.common.passengercount.json; -import com.dslplatform.json.CompiledJson; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.List; -@CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) +@JsonIgnoreProperties(ignoreUnknown = true) public class DoorCount { public String door; public List count; diff --git a/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java b/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java index 28aaa8e8..1c30eaab 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java +++ b/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java @@ -1,10 +1,11 @@ package fi.hsl.common.passengercount.json; -import com.dslplatform.json.CompiledJson; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.List; -@CompiledJson(onUnknown = CompiledJson.Behavior.IGNORE) +@JsonIgnoreProperties(ignoreUnknown = true) public class Vehiclecounts { public String countquality; public int vehicleload; From 6c2ce42d1c8341c229114670fb31c7d42f839260 Mon Sep 17 00:00:00 2001 From: bogdandina Date: Mon, 8 Dec 2025 16:32:08 +0200 Subject: [PATCH 5/9] feat(70552): remove duplicated dependency --- pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pom.xml b/pom.xml index 31e32bc2..134a4e5a 100644 --- a/pom.xml +++ b/pom.xml @@ -113,11 +113,6 @@ slf4j-api 2.0.7 - - com.fasterxml.jackson.core - jackson-databind - 2.15.0 - org.jetbrains annotations From 054d8a166a093ab6c36847f7a965442becadb518 Mon Sep 17 00:00:00 2001 From: bogdandina Date: Mon, 8 Dec 2025 17:12:42 +0200 Subject: [PATCH 6/9] feat(70552): fix one more warning --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 134a4e5a..54896381 100644 --- a/pom.xml +++ b/pom.xml @@ -187,6 +187,7 @@ org.apache.maven.plugins maven-jar-plugin + 3.4.1 From 6fd089b00841b7ece5bd0b625faca6b626e2724d Mon Sep 17 00:00:00 2001 From: bogdandina Date: Tue, 9 Dec 2025 08:50:50 +0200 Subject: [PATCH 7/9] feat(70552): refactoring and fixes --- .../java/fi/hsl/common/hfp/HfpParser.java | 1 - .../hsl/common/passengercount/json/Apc.java | 2 +- .../PassengerCountParserTest.java | 25 ++++++++---- ...enger-count-unknown-properties-sample.json | 39 +++++++++++++++++++ 4 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 src/test/resources/passenger-count-unknown-properties-sample.json diff --git a/src/main/java/fi/hsl/common/hfp/HfpParser.java b/src/main/java/fi/hsl/common/hfp/HfpParser.java index b7c9e3da..d2a82f05 100644 --- a/src/main/java/fi/hsl/common/hfp/HfpParser.java +++ b/src/main/java/fi/hsl/common/hfp/HfpParser.java @@ -1,6 +1,5 @@ package fi.hsl.common.hfp; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; diff --git a/src/main/java/fi/hsl/common/passengercount/json/Apc.java b/src/main/java/fi/hsl/common/passengercount/json/Apc.java index 8ef28eb5..d59770c1 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/Apc.java +++ b/src/main/java/fi/hsl/common/passengercount/json/Apc.java @@ -5,7 +5,7 @@ import java.util.Date; -@JsonIgnoreProperties +@JsonIgnoreProperties(ignoreUnknown = true) public class Apc { public String desi; public String dir; diff --git a/src/test/java/fi/hsl/common/passengercount/PassengerCountParserTest.java b/src/test/java/fi/hsl/common/passengercount/PassengerCountParserTest.java index d311772e..8e4f3391 100644 --- a/src/test/java/fi/hsl/common/passengercount/PassengerCountParserTest.java +++ b/src/test/java/fi/hsl/common/passengercount/PassengerCountParserTest.java @@ -18,17 +18,16 @@ public class PassengerCountParserTest { private final String TEST_TOPIC = "/hfp/v2/journey/ongoing/apc/bus/0022/01288"; + @Test + public void parseJson_ignoreUnknownProperties_Test() throws Exception { + final var apc = parseJsonFromResources("src/test/resources/passenger-count-unknown-properties-sample.json").apc; + performAssertions(apc); + } + @Test public void parseJsonTest() throws Exception { Apc apc = parseJsonFromResources("src/test/resources/passenger-count-sample.json").apc; - assertEquals("555", apc.desi); - assertEquals(12, (int) apc.oper); - assertEquals("GPS", apc.loc); - assertEquals("regular | defect | other", apc.vehiclecounts.countquality); - assertEquals(15, apc.vehiclecounts.vehicleload); - assertEquals(1, apc.vehiclecounts.doorcounts.size()); - assertEquals("door1", apc.vehiclecounts.doorcounts.get(0).door); - + performAssertions(apc); } private ApcJson parseJsonFromResources(String filename) throws Exception { @@ -38,6 +37,16 @@ private ApcJson parseJsonFromResources(String filename) throws Exception { return apcJson; } + private void performAssertions(Apc apc) { + assertEquals("555", apc.desi); + assertEquals(12, (int) apc.oper); + assertEquals("GPS", apc.loc); + assertEquals("regular | defect | other", apc.vehiclecounts.countquality); + assertEquals(15, apc.vehiclecounts.vehicleload); + assertEquals(1, apc.vehiclecounts.doorcounts.size()); + assertEquals("door1", apc.vehiclecounts.doorcounts.get(0).door); + } + @Test public void convertJsonToProtobufMessageTest() throws Exception { ApcJson apcJson = parseJsonFromResources("src/test/resources/passenger-count-sample.json"); diff --git a/src/test/resources/passenger-count-unknown-properties-sample.json b/src/test/resources/passenger-count-unknown-properties-sample.json new file mode 100644 index 00000000..53e453eb --- /dev/null +++ b/src/test/resources/passenger-count-unknown-properties-sample.json @@ -0,0 +1,39 @@ +{ + "APC": { + "desi": "555", + "dir": "1", + "oper": 12, + "veh": 10, + "tst": "2019-05-23T14:15:16.000Z", + "tsi": 1416308975, + "lat": 24.9435, + "long": 60.1967, + "odo": 45.12, + "oday": "2019-05-23", + "jrn": 1, + "invalid": true, + "line": 264, + "start": "13:40", + "loc": "GPS", + "stop": 1234567, + "route": "2551", + "vehiclecounts": { + "countquality": "regular | defect | other", + "vehicleload": 15, + "vehicleloadratio": 0.2, + "doorcounts": [ + { + "door" : "door1", + "count": [ + { + "class": "adult | child | pram | bike | wheelchair | other", + "in": 1, + "out": 2 + } + ] + } + ], + "extensions": "extension data" + } + } +} \ No newline at end of file From f62a789e7438969cee1cde6bb51f375ebd29d51c Mon Sep 17 00:00:00 2001 From: bogdandina Date: Tue, 9 Dec 2025 12:19:58 +0200 Subject: [PATCH 8/9] feat(70552): fix version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 54896381..f83b2788 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 fi.hsl transitdata-common - 3.0.1 + 3.0.0 jar Common utilities for Transitdata projects From 200e8a2ebd1049ccae397b09d167f759d9588139 Mon Sep 17 00:00:00 2001 From: bogdandina Date: Wed, 10 Dec 2025 16:07:10 +0200 Subject: [PATCH 9/9] feat(70552): fix spotless --- src/main/java/fi/hsl/common/hfp/HfpJson.java | 8 +++----- .../hsl/common/passengercount/PassengerCountParser.java | 7 ++----- .../java/fi/hsl/common/passengercount/json/ApcJson.java | 1 - .../fi/hsl/common/passengercount/json/Vehiclecounts.java | 1 - 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/main/java/fi/hsl/common/hfp/HfpJson.java b/src/main/java/fi/hsl/common/hfp/HfpJson.java index afa8c043..6b1296cb 100644 --- a/src/main/java/fi/hsl/common/hfp/HfpJson.java +++ b/src/main/java/fi/hsl/common/hfp/HfpJson.java @@ -22,9 +22,8 @@ public class HfpJson { // {"VP":{"desi":"81","dir":"2","oper":22,"veh":792,"tst":"2018-04-05T17:38:36Z","tsi":1522949916,"spd":0.16,"hdg":225,"lat":60.194481,"long":25.03095,"acc":0,"dl":-25,"odo":2819,"drst":0,"oday":"2018-04-05","jrn":636,"line":112,"start":"20:25"}} @JsonProperty("VP") - @JsonAlias({"DUE", "ARR", "DEP", "ARS", "PDE", "PAS", "WAIT", - "DOO", "DOC", "TLR", "TLA", "DA", "DOUT", "BA", "BOUT", - "VJA", "VJOUT"}) + @JsonAlias({"DUE", "ARR", "DEP", "ARS", "PDE", "PAS", "WAIT", "DOO", "DOC", "TLR", "TLA", "DA", "DOUT", "BA", + "BOUT", "VJA", "VJOUT"}) public Payload payload; @JsonIgnoreProperties(ignoreUnknown = true) @@ -142,8 +141,7 @@ public Double deserialize(JsonParser p, DeserializationContext ctxt) public static class OdoSerializer extends JsonSerializer { @Override - public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { + public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == null) { gen.writeNull(); } else { diff --git a/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java b/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java index 00a307e1..17605ca8 100644 --- a/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java +++ b/src/main/java/fi/hsl/common/passengercount/PassengerCountParser.java @@ -21,8 +21,7 @@ public class PassengerCountParser { static final Pattern topicVersionRegex = Pattern.compile("(^v\\d+|dev)"); - ObjectMapper objectMapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true) .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); @@ -274,9 +273,7 @@ public ApcJson parseJson(byte @NotNull [] data) throws IOException, InvalidAPCPa return objectMapper.readValue(data, ApcJson.class); } catch (IOException ioe) { if (ioe instanceof com.fasterxml.jackson.core.JsonProcessingException jpe) { - throw new PassengerCountParser.InvalidAPCPayloadException( - "Failed to parse APC JSON", jpe - ); + throw new PassengerCountParser.InvalidAPCPayloadException("Failed to parse APC JSON", jpe); } else { throw ioe; } diff --git a/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java b/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java index aa2b2cd5..2aac3d58 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java +++ b/src/main/java/fi/hsl/common/passengercount/json/ApcJson.java @@ -1,6 +1,5 @@ package fi.hsl.common.passengercount.json; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java b/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java index 1c30eaab..ee783dc2 100644 --- a/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java +++ b/src/main/java/fi/hsl/common/passengercount/json/Vehiclecounts.java @@ -1,6 +1,5 @@ package fi.hsl.common.passengercount.json; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.List;