From e78d7d6ea82bde70f5eed7ad046f29ef9e632eb6 Mon Sep 17 00:00:00 2001 From: trifonovt <87468028+TihomirTrifonov@users.noreply.github.com> Date: Fri, 12 Jun 2026 16:34:37 +0200 Subject: [PATCH] Adjust runtime mixing and vehicle unit extraction --- .../mixing/RuntimeEventDescriptorFactory.java | 15 +- .../RuntimeEventMixingRuleRegistry.java | 69 +++++- ...riverWorkingTimeRuntimeProcessingPlan.java | 8 +- .../mixing/RuntimeEventMixingServiceTest.java | 219 +++++++++++++++++- 4 files changed, 292 insertions(+), 19 deletions(-) diff --git a/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventDescriptorFactory.java b/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventDescriptorFactory.java index ddbf339..105cff7 100644 --- a/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventDescriptorFactory.java +++ b/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventDescriptorFactory.java @@ -143,6 +143,8 @@ public class RuntimeEventDescriptorFactory { case POSITION -> prefix + "_POSITION"; case PLACE -> prefix + "_PLACE"; case BORDER_CROSSING -> prefix + "_BORDER_CROSSING"; + case LOAD_UNLOAD -> prefix + "_LOAD_UNLOAD"; + case SPECIFIC_CONDITION -> prefix + "_SPECIFIC_CONDITION"; case SPEEDING -> Objects.equals("VU", prefix) ? "SPEEDING_EVENTS" : null; default -> null; }; @@ -203,7 +205,7 @@ public class RuntimeEventDescriptorFactory { nullToEmpty(RuntimeEntityReferenceResolver.driverKey(event)), nullToEmpty(event == null || event.eventDomain() == null ? null : event.eventDomain().name()), nullToEmpty(event == null || event.eventType() == null ? null : event.eventType().name()), - nullToEmpty(event == null || event.lifecycle() == null ? null : event.lifecycle().name()), + nullToEmpty(semanticSupportLifecycle(event)), normalizeTime(event == null ? null : event.occurredAt()), nullToEmpty(RuntimeEntityReferenceResolver.registrationKey(event)), nullToEmpty(firstNonBlank(text(raw, "latitude"), position == null || position.latitude() == null ? null : position.latitude().toPlainString())), @@ -217,6 +219,17 @@ public class RuntimeEventDescriptorFactory { ); } + private String semanticSupportLifecycle(EventHubEventDto event) { + if (event == null || event.lifecycle() == null) { + return null; + } + if (event.eventDomain() == EventDomain.PLACE + && (event.lifecycle() == EventLifecycle.START || event.lifecycle() == EventLifecycle.BEGIN)) { + return EventLifecycle.BEGIN.name(); + } + return event.lifecycle().name(); + } + private JsonNode rawPayload(EventHubEventDto event) { return RuntimeEntityReferenceResolver.rawPayload(event); } diff --git a/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingRuleRegistry.java b/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingRuleRegistry.java index 321bc5e..b3d0e93 100644 --- a/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingRuleRegistry.java +++ b/src/main/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingRuleRegistry.java @@ -10,6 +10,53 @@ import org.springframework.stereotype.Component; @Component public class RuntimeEventMixingRuleRegistry { + private static final Set SUPPORT_EVENT_DOMAINS = Set.of( + EventDomain.POSITION, + EventDomain.PLACE, + EventDomain.BORDER_CROSSING, + EventDomain.LOAD_UNLOAD, + EventDomain.SPECIFIC_CONDITION + ); + + private static final Set SUPPORT_EVENT_TYPES = Set.of( + EventType.POSITION_RECORDED, + EventType.WORKING_DAY_PLACE_RECORDED, + EventType.BORDER_INBOUND, + EventType.BORDER_OUTBOUND, + EventType.BORDER_OUT_EU, + EventType.LOAD, + EventType.UNLOAD, + EventType.LOAD_UNLOAD, + EventType.OUT, + EventType.FERRY_TRAIN + ); + + private static final Set SUPPORT_EVENT_LIFECYCLES = Set.of( + EventLifecycle.SNAPSHOT, + EventLifecycle.START, + EventLifecycle.BEGIN, + EventLifecycle.END, + EventLifecycle.INBOUND, + EventLifecycle.OUTBOUND, + EventLifecycle.OUT_EU + ); + + private static final Set CARD_SUPPORT_EXTRACTION_CODES = Set.of( + "CARD_POSITION", + "CARD_PLACE", + "CARD_BORDER_CROSSING", + "CARD_LOAD_UNLOAD", + "CARD_SPECIFIC_CONDITION" + ); + + private static final Set VU_SUPPORT_EXTRACTION_CODES = Set.of( + "VU_POSITION", + "VU_PLACE", + "VU_BORDER_CROSSING", + "VU_LOAD_UNLOAD", + "VU_SPECIFIC_CONDITION" + ); + public List rulesForMode(String mode) { if (RuntimeEventMixingService.MODE_OFF.equals(mode)) { return List.of(); @@ -61,12 +108,11 @@ public class RuntimeEventMixingRuleRegistry { RuntimeEventMixingService.RULE_TACHOGRAPH_CARD_VU_SUPPORT_SAME_EVENT_KEY, RuntimeEventMixingChannel.SUPPORT_EVIDENCE, RuntimeEventMixingRule.EQUIVALENCE_EXACT_EVENT_KEY, - Set.of(EventDomain.POSITION, EventDomain.PLACE, EventDomain.BORDER_CROSSING), - Set.of(EventType.POSITION_RECORDED, EventType.WORKING_DAY_PLACE_RECORDED, - EventType.BORDER_INBOUND, EventType.BORDER_OUTBOUND, EventType.BORDER_OUT_EU), - Set.of(EventLifecycle.SNAPSHOT, EventLifecycle.INBOUND, EventLifecycle.OUTBOUND, EventLifecycle.OUT_EU), - Set.of("CARD_POSITION", "CARD_PLACE", "CARD_BORDER_CROSSING"), - Set.of("VU_POSITION", "VU_PLACE", "VU_BORDER_CROSSING"), + SUPPORT_EVENT_DOMAINS, + SUPPORT_EVENT_TYPES, + SUPPORT_EVENT_LIFECYCLES, + CARD_SUPPORT_EXTRACTION_CODES, + VU_SUPPORT_EXTRACTION_CODES, RuntimeResolvedEventRole.FUSED_PRIMARY, RuntimeResolvedEventRole.SUPPRESSED_DUPLICATE, "FUSED_PRIMARY_SELECTED", @@ -79,12 +125,11 @@ public class RuntimeEventMixingRuleRegistry { RuntimeEventMixingService.RULE_TACHOGRAPH_CARD_VU_SUPPORT_COMPATIBLE_KEY, RuntimeEventMixingChannel.SUPPORT_EVIDENCE, RuntimeEventMixingRule.EQUIVALENCE_COMPATIBLE_SUPPORT_KEY, - Set.of(EventDomain.POSITION, EventDomain.PLACE, EventDomain.BORDER_CROSSING), - Set.of(EventType.POSITION_RECORDED, EventType.WORKING_DAY_PLACE_RECORDED, - EventType.BORDER_INBOUND, EventType.BORDER_OUTBOUND, EventType.BORDER_OUT_EU), - Set.of(EventLifecycle.SNAPSHOT, EventLifecycle.INBOUND, EventLifecycle.OUTBOUND, EventLifecycle.OUT_EU), - Set.of("CARD_POSITION", "CARD_PLACE", "CARD_BORDER_CROSSING"), - Set.of("VU_POSITION", "VU_PLACE", "VU_BORDER_CROSSING"), + SUPPORT_EVENT_DOMAINS, + SUPPORT_EVENT_TYPES, + SUPPORT_EVENT_LIFECYCLES, + CARD_SUPPORT_EXTRACTION_CODES, + VU_SUPPORT_EXTRACTION_CODES, RuntimeResolvedEventRole.FUSED_PRIMARY, RuntimeResolvedEventRole.SUPPRESSED_DUPLICATE, "FUSED_PRIMARY_SELECTED", diff --git a/src/main/java/at/procon/eventhub/processing/eventprocessing/plan/DriverWorkingTimeRuntimeProcessingPlan.java b/src/main/java/at/procon/eventhub/processing/eventprocessing/plan/DriverWorkingTimeRuntimeProcessingPlan.java index 88f3239..26e17cc 100644 --- a/src/main/java/at/procon/eventhub/processing/eventprocessing/plan/DriverWorkingTimeRuntimeProcessingPlan.java +++ b/src/main/java/at/procon/eventhub/processing/eventprocessing/plan/DriverWorkingTimeRuntimeProcessingPlan.java @@ -215,22 +215,22 @@ public class DriverWorkingTimeRuntimeProcessingPlan implements RuntimeProcessing boolean includeExecutionModuleResults = booleanParameter( request.parameters(), INCLUDE_EXECUTION_MODULE_RESULTS_PARAMETER, - true + false ); boolean includePartitionMetadata = booleanParameter( request.parameters(), INCLUDE_PARTITION_METADATA_PARAMETER, - true + false ); boolean includePartitionModuleResults = booleanParameter( request.parameters(), INCLUDE_PARTITION_MODULE_RESULTS_PARAMETER, - true + false ); boolean includeSupportEvidenceNormalization = booleanParameter( request.parameters(), INCLUDE_SUPPORT_EVIDENCE_NORMALIZATION_PARAMETER, - true + false ); int vehicleEvidencePaddingMinutes = resolveVehicleEvidencePaddingMinutes( request.sourceSelection(), diff --git a/src/test/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingServiceTest.java b/src/test/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingServiceTest.java index b669258..d521f8b 100644 --- a/src/test/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingServiceTest.java +++ b/src/test/java/at/procon/eventhub/processing/eventprocessing/mixing/RuntimeEventMixingServiceTest.java @@ -148,7 +148,7 @@ class RuntimeEventMixingServiceTest { "TACHOGRAPH:CARD_PLACE:1", EventDomain.PLACE, EventType.WORKING_DAY_PLACE_RECORDED, - EventLifecycle.SNAPSHOT, + EventLifecycle.START, false ); EventHubEventDto vuPlace = supportEvidence( @@ -157,7 +157,7 @@ class RuntimeEventMixingServiceTest { "TACHOGRAPH:VU_PLACE:2", EventDomain.PLACE, EventType.WORKING_DAY_PLACE_RECORDED, - EventLifecycle.SNAPSHOT, + EventLifecycle.START, true ); EventHubEventDto cardBorder = supportEvidence( @@ -188,6 +188,72 @@ class RuntimeEventMixingServiceTest { assertThat(mixed.eventMixingDecisions()).hasSize(2); } + @Test + void suppressesVuPlaceDuplicateForFileSessionBeginLifecycle() { + EventHubEventDto cardPlace = fileSessionSupportEvidence( + "DRIVER_CARD", + "TACHOGRAPH_FILE_SESSION:11111111-1111-1111-1111-111111111111:SUPPORT:card-place-1:BEGIN:2026-04-01T00:00:00Z", + EventDomain.PLACE, + EventType.WORKING_DAY_PLACE_RECORDED, + EventLifecycle.BEGIN, + false + ); + EventHubEventDto vuPlace = fileSessionSupportEvidence( + "VEHICLE_UNIT", + "TACHOGRAPH_FILE_SESSION:22222222-2222-2222-2222-222222222222:SUPPORT:vu-place-1:BEGIN:2026-04-01T00:00:00Z", + EventDomain.PLACE, + EventType.WORKING_DAY_PLACE_RECORDED, + EventLifecycle.BEGIN, + true + ); + + RuntimeMixedEventBundle mixed = service.mix( + List.of(cardPlace, vuPlace), + RuntimeEventMixingService.MODE_TACHOGRAPH_SAME_SOURCE + ); + + assertThat(mixed.supportEvidenceEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactly("TACHOGRAPH_FILE_SESSION:11111111-1111-1111-1111-111111111111:SUPPORT:card-place-1:BEGIN:2026-04-01T00:00:00Z"); + assertThat(mixed.suppressedEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactly("TACHOGRAPH_FILE_SESSION:22222222-2222-2222-2222-222222222222:SUPPORT:vu-place-1:BEGIN:2026-04-01T00:00:00Z"); + assertThat(mixed.eventMixingDecisions()).hasSize(1); + } + + @Test + void treatsStartAndBeginAsEquivalentPlaceLifecycles() { + EventHubEventDto cardPlace = supportEvidence( + "CARD_PLACE", + "DRIVER_CARD", + "TACHOGRAPH:CARD_PLACE:START", + EventDomain.PLACE, + EventType.WORKING_DAY_PLACE_RECORDED, + EventLifecycle.START, + false + ); + EventHubEventDto vuPlace = supportEvidence( + "VU_PLACE", + "VEHICLE_UNIT", + "TACHOGRAPH:VU_PLACE:BEGIN", + EventDomain.PLACE, + EventType.WORKING_DAY_PLACE_RECORDED, + EventLifecycle.BEGIN, + true + ); + + RuntimeMixedEventBundle mixed = service.mix( + List.of(cardPlace, vuPlace), + RuntimeEventMixingService.MODE_TACHOGRAPH_SAME_SOURCE + ); + + assertThat(mixed.supportEvidenceEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactly("TACHOGRAPH:CARD_PLACE:START"); + assertThat(mixed.suppressedEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactly("TACHOGRAPH:VU_PLACE:BEGIN"); + assertThat(mixed.eventMixingDecisions()).hasSize(1); + assertThat(mixed.eventMixingDecisions().getFirst().ruleId()) + .isEqualTo(RuntimeEventMixingService.RULE_TACHOGRAPH_CARD_VU_SUPPORT_COMPATIBLE_KEY); + } + @Test void suppressesTachographFileSessionVuPositionDuplicateWhenNoExtractionCodeIsPresent() { EventHubEventDto card = fileSessionSupportEvidence( @@ -220,6 +286,143 @@ class RuntimeEventMixingServiceTest { .containsExactly("VU_POSITION"); } + @Test + void suppressesVuDuplicatesForAllAdditionalSupportEventTypes() { + EventHubEventDto cardLoad = supportEvidence( + "CARD_LOAD_UNLOAD", "DRIVER_CARD", "TACHOGRAPH:CARD_LOAD_UNLOAD:LOAD", + EventDomain.LOAD_UNLOAD, EventType.LOAD, EventLifecycle.SNAPSHOT, false + ); + EventHubEventDto vuLoad = supportEvidence( + "VU_LOAD_UNLOAD", "VEHICLE_UNIT", "TACHOGRAPH:VU_LOAD_UNLOAD:LOAD", + EventDomain.LOAD_UNLOAD, EventType.LOAD, EventLifecycle.SNAPSHOT, true + ); + EventHubEventDto cardUnload = supportEvidence( + "CARD_LOAD_UNLOAD", "DRIVER_CARD", "TACHOGRAPH:CARD_LOAD_UNLOAD:UNLOAD", + EventDomain.LOAD_UNLOAD, EventType.UNLOAD, EventLifecycle.SNAPSHOT, false + ); + EventHubEventDto vuUnload = supportEvidence( + "VU_LOAD_UNLOAD", "VEHICLE_UNIT", "TACHOGRAPH:VU_LOAD_UNLOAD:UNLOAD", + EventDomain.LOAD_UNLOAD, EventType.UNLOAD, EventLifecycle.SNAPSHOT, true + ); + EventHubEventDto cardLoadUnload = supportEvidence( + "CARD_LOAD_UNLOAD", "DRIVER_CARD", "TACHOGRAPH:CARD_LOAD_UNLOAD:LOAD_UNLOAD", + EventDomain.LOAD_UNLOAD, EventType.LOAD_UNLOAD, EventLifecycle.SNAPSHOT, false + ); + EventHubEventDto vuLoadUnload = supportEvidence( + "VU_LOAD_UNLOAD", "VEHICLE_UNIT", "TACHOGRAPH:VU_LOAD_UNLOAD:LOAD_UNLOAD", + EventDomain.LOAD_UNLOAD, EventType.LOAD_UNLOAD, EventLifecycle.SNAPSHOT, true + ); + EventHubEventDto cardOut = supportEvidence( + "CARD_SPECIFIC_CONDITION", "DRIVER_CARD", "TACHOGRAPH:CARD_SPECIFIC_CONDITION:OUT:BEGIN", + EventDomain.SPECIFIC_CONDITION, EventType.OUT, EventLifecycle.BEGIN, false + ); + EventHubEventDto vuOut = supportEvidence( + "VU_SPECIFIC_CONDITION", "VEHICLE_UNIT", "TACHOGRAPH:VU_SPECIFIC_CONDITION:OUT:BEGIN", + EventDomain.SPECIFIC_CONDITION, EventType.OUT, EventLifecycle.BEGIN, true + ); + EventHubEventDto cardFerryTrain = supportEvidence( + "CARD_SPECIFIC_CONDITION", "DRIVER_CARD", "TACHOGRAPH:CARD_SPECIFIC_CONDITION:FERRY_TRAIN:END", + EventDomain.SPECIFIC_CONDITION, EventType.FERRY_TRAIN, EventLifecycle.END, false + ); + EventHubEventDto vuFerryTrain = supportEvidence( + "VU_SPECIFIC_CONDITION", "VEHICLE_UNIT", "TACHOGRAPH:VU_SPECIFIC_CONDITION:FERRY_TRAIN:END", + EventDomain.SPECIFIC_CONDITION, EventType.FERRY_TRAIN, EventLifecycle.END, true + ); + + RuntimeMixedEventBundle mixed = service.mix( + List.of( + cardLoad, vuLoad, + cardUnload, vuUnload, + cardLoadUnload, vuLoadUnload, + cardOut, vuOut, + cardFerryTrain, vuFerryTrain + ), + RuntimeEventMixingService.MODE_TACHOGRAPH_SAME_SOURCE + ); + + assertThat(mixed.supportEvidenceEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactlyInAnyOrder( + "TACHOGRAPH:CARD_LOAD_UNLOAD:LOAD", + "TACHOGRAPH:CARD_LOAD_UNLOAD:UNLOAD", + "TACHOGRAPH:CARD_LOAD_UNLOAD:LOAD_UNLOAD", + "TACHOGRAPH:CARD_SPECIFIC_CONDITION:OUT:BEGIN", + "TACHOGRAPH:CARD_SPECIFIC_CONDITION:FERRY_TRAIN:END" + ); + assertThat(mixed.suppressedEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactlyInAnyOrder( + "TACHOGRAPH:VU_LOAD_UNLOAD:LOAD", + "TACHOGRAPH:VU_LOAD_UNLOAD:UNLOAD", + "TACHOGRAPH:VU_LOAD_UNLOAD:LOAD_UNLOAD", + "TACHOGRAPH:VU_SPECIFIC_CONDITION:OUT:BEGIN", + "TACHOGRAPH:VU_SPECIFIC_CONDITION:FERRY_TRAIN:END" + ); + assertThat(mixed.eventMixingDecisions()).hasSize(5); + assertThat(mixed.eventMixingDecisions()) + .allSatisfy(decision -> assertThat(decision.secondaryExtractionCodes()).hasSize(1)); + assertThat(mixed.eventMixingDecisions()) + .extracting(decision -> decision.secondaryExtractionCodes().getFirst()) + .containsExactlyInAnyOrder( + "VU_LOAD_UNLOAD", "VU_LOAD_UNLOAD", "VU_LOAD_UNLOAD", + "VU_SPECIFIC_CONDITION", "VU_SPECIFIC_CONDITION" + ); + } + + @Test + void suppressesFileSessionVuLoadUnloadAndSpecificConditionDuplicatesWithoutExtractionCodes() { + EventHubEventDto cardLoad = fileSessionSupportEvidence( + "DRIVER_CARD", + "TACHOGRAPH_FILE_SESSION:11111111-1111-1111-1111-111111111111:SUPPORT:card-load-1:SNAPSHOT:2026-04-01T00:00:00Z", + EventDomain.LOAD_UNLOAD, + EventType.LOAD, + EventLifecycle.SNAPSHOT, + false + ); + EventHubEventDto vuLoad = fileSessionSupportEvidence( + "VEHICLE_UNIT", + "TACHOGRAPH_FILE_SESSION:22222222-2222-2222-2222-222222222222:SUPPORT:vu-load-1:SNAPSHOT:2026-04-01T00:00:00Z", + EventDomain.LOAD_UNLOAD, + EventType.LOAD, + EventLifecycle.SNAPSHOT, + true + ); + EventHubEventDto cardOut = fileSessionSupportEvidence( + "DRIVER_CARD", + "TACHOGRAPH_FILE_SESSION:11111111-1111-1111-1111-111111111111:SUPPORT:card-out-1:BEGIN:2026-04-01T00:00:00Z", + EventDomain.SPECIFIC_CONDITION, + EventType.OUT, + EventLifecycle.BEGIN, + false + ); + EventHubEventDto vuOut = fileSessionSupportEvidence( + "VEHICLE_UNIT", + "TACHOGRAPH_FILE_SESSION:22222222-2222-2222-2222-222222222222:SUPPORT:vu-out-1:BEGIN:2026-04-01T00:00:00Z", + EventDomain.SPECIFIC_CONDITION, + EventType.OUT, + EventLifecycle.BEGIN, + true + ); + + RuntimeMixedEventBundle mixed = service.mix( + List.of(cardLoad, vuLoad, cardOut, vuOut), + RuntimeEventMixingService.MODE_TACHOGRAPH_SAME_SOURCE + ); + + assertThat(mixed.supportEvidenceEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactlyInAnyOrder( + cardLoad.externalSourceEventId(), + cardOut.externalSourceEventId() + ); + assertThat(mixed.suppressedEvents()).extracting(EventHubEventDto::externalSourceEventId) + .containsExactlyInAnyOrder( + vuLoad.externalSourceEventId(), + vuOut.externalSourceEventId() + ); + assertThat(mixed.eventMixingDecisions()).hasSize(2); + assertThat(mixed.eventMixingDecisions()) + .extracting(decision -> decision.secondaryExtractionCodes().getFirst()) + .containsExactlyInAnyOrder("VU_LOAD_UNLOAD", "VU_SPECIFIC_CONDITION"); + } + private EventHubEventDto activity(String extractionCode, String sourceKind, String externalId) { ObjectNode raw = baseRaw(extractionCode, sourceKind); raw.put("activityType", "BREAK_REST"); @@ -264,6 +467,9 @@ class RuntimeEventMixingServiceTest { raw.put("region", "W"); raw.put("countryFrom", "AT"); raw.put("countryTo", "DE"); + if (domain == EventDomain.LOAD_UNLOAD) { + raw.put("operation", type.name()); + } ObjectNode payload = JsonNodeFactory.instance.objectNode(); payload.set("raw", raw); ObjectNode attributes = JsonNodeFactory.instance.objectNode(); @@ -271,6 +477,9 @@ class RuntimeEventMixingServiceTest { attributes.put("region", "W"); attributes.put("countryFrom", "AT"); attributes.put("countryTo", "DE"); + if (domain == EventDomain.LOAD_UNLOAD) { + attributes.put("operation", type.name()); + } VehicleRefDto vehicleRef = withVin ? new VehicleRefDto("1:VEHICLE-ID", "WDB9634031L123456", "1:REG-ID", new VehicleRegistrationRefDto("1", 1, "LL-158TE")) : new VehicleRefDto(null, null, "1:REG-ID", new VehicleRegistrationRefDto("1", 1, "LL-158TE")); @@ -330,6 +539,9 @@ class RuntimeEventMixingServiceTest { raw.put("region", "W"); raw.put("countryFrom", "AT"); raw.put("countryTo", "DE"); + if (domain == EventDomain.LOAD_UNLOAD) { + raw.put("operation", type.name()); + } ObjectNode payload = JsonNodeFactory.instance.objectNode(); payload.set("raw", raw); ObjectNode attributes = JsonNodeFactory.instance.objectNode(); @@ -337,6 +549,9 @@ class RuntimeEventMixingServiceTest { attributes.put("region", "W"); attributes.put("countryFrom", "AT"); attributes.put("countryTo", "DE"); + if (domain == EventDomain.LOAD_UNLOAD) { + attributes.put("operation", type.name()); + } VehicleRefDto vehicleRef = withVin ? new VehicleRefDto("1:VEHICLE-ID", "WDB9634031L123456", "1:REG-ID", new VehicleRegistrationRefDto("1", 1, "LL-158TE")) : new VehicleRefDto(null, null, "1:REG-ID", new VehicleRegistrationRefDto("1", 1, "LL-158TE"));