Fix tachograph runtime identity and interval extraction
This commit is contained in:
parent
927ac3b903
commit
6dd1fb7447
|
|
@ -26,7 +26,7 @@ public record DriverRefDto(
|
||||||
|
|
||||||
public String stableKey() {
|
public String stableKey() {
|
||||||
String cardKey = driverCard == null ? "" : driverCard.stableKey();
|
String cardKey = driverCard == null ? "" : driverCard.stableKey();
|
||||||
return (sourceEntityId == null ? "" : sourceEntityId) + "|" + cardKey;
|
return /*(sourceEntityId == null ? "" : sourceEntityId) + "|" +*/ cardKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String normalizeNullable(String value) {
|
private static String normalizeNullable(String value) {
|
||||||
|
|
|
||||||
|
|
@ -148,13 +148,13 @@ public class EventHubEventReadRepository {
|
||||||
event.source_package_entity_id,
|
event.source_package_entity_id,
|
||||||
detail.detail_type,
|
detail.detail_type,
|
||||||
detail.attributes,
|
detail.attributes,
|
||||||
driver.source_driver_entity_id,
|
driver_identity.source_driver_entity_id,
|
||||||
driver_card.nation as driver_card_nation,
|
driver_card.nation as driver_card_nation,
|
||||||
driver_card.nation_numeric_code as driver_card_nation_numeric_code,
|
driver_card.nation_numeric_code as driver_card_nation_numeric_code,
|
||||||
driver_card.card_number as driver_card_number,
|
driver_card.card_number as driver_card_number,
|
||||||
vehicle.source_vehicle_entity_id,
|
vehicle_identity.source_vehicle_entity_id,
|
||||||
vehicle.vin,
|
vehicle.vin,
|
||||||
registration.source_registration_entity_id,
|
registration_identity.source_registration_entity_id,
|
||||||
registration.nation as vehicle_registration_nation,
|
registration.nation as vehicle_registration_nation,
|
||||||
registration.nation_numeric_code as vehicle_registration_nation_numeric_code,
|
registration.nation_numeric_code as vehicle_registration_nation_numeric_code,
|
||||||
registration.registration_number as vehicle_registration_number,
|
registration.registration_number as vehicle_registration_number,
|
||||||
|
|
@ -173,9 +173,36 @@ public class EventHubEventReadRepository {
|
||||||
limit 1
|
limit 1
|
||||||
) detail on true
|
) detail on true
|
||||||
left join eventhub.driver driver on driver.id = event.driver_id
|
left join eventhub.driver driver on driver.id = event.driver_id
|
||||||
|
left join lateral (
|
||||||
|
select identity.source_driver_entity_id
|
||||||
|
from eventhub.source_driver_identity identity
|
||||||
|
where identity.driver_id = event.driver_id
|
||||||
|
and identity.tenant_key = package.tenant_key
|
||||||
|
and identity.event_source_id = event.event_source_id
|
||||||
|
order by identity.updated_at desc, identity.created_at desc, identity.id
|
||||||
|
limit 1
|
||||||
|
) driver_identity on true
|
||||||
left join eventhub.driver_card driver_card on driver_card.id = event.driver_card_id
|
left join eventhub.driver_card driver_card on driver_card.id = event.driver_card_id
|
||||||
left join eventhub.vehicle vehicle on vehicle.id = event.vehicle_id
|
left join eventhub.vehicle vehicle on vehicle.id = event.vehicle_id
|
||||||
|
left join lateral (
|
||||||
|
select identity.source_vehicle_entity_id
|
||||||
|
from eventhub.source_vehicle_identity identity
|
||||||
|
where identity.vehicle_id = event.vehicle_id
|
||||||
|
and identity.tenant_key = package.tenant_key
|
||||||
|
and identity.event_source_id = event.event_source_id
|
||||||
|
order by identity.updated_at desc, identity.created_at desc, identity.id
|
||||||
|
limit 1
|
||||||
|
) vehicle_identity on true
|
||||||
left join eventhub.vehicle_registration registration on registration.id = event.vehicle_registration_id
|
left join eventhub.vehicle_registration registration on registration.id = event.vehicle_registration_id
|
||||||
|
left join lateral (
|
||||||
|
select identity.source_registration_entity_id
|
||||||
|
from eventhub.source_vehicle_registration_identity identity
|
||||||
|
where identity.vehicle_registration_id = event.vehicle_registration_id
|
||||||
|
and identity.tenant_key = package.tenant_key
|
||||||
|
and identity.event_source_id = event.event_source_id
|
||||||
|
order by identity.updated_at desc, identity.created_at desc, identity.id
|
||||||
|
limit 1
|
||||||
|
) registration_identity on true
|
||||||
where package.tenant_key = ?
|
where package.tenant_key = ?
|
||||||
and source.provider_key = ?
|
and source.provider_key = ?
|
||||||
"""
|
"""
|
||||||
|
|
@ -205,7 +232,18 @@ public class EventHubEventReadRepository {
|
||||||
params.add(occurredTo);
|
params.add(occurredTo);
|
||||||
}
|
}
|
||||||
if (driverSourceEntityId != null) {
|
if (driverSourceEntityId != null) {
|
||||||
sql.append(" and driver.source_driver_entity_id = ?");
|
sql.append(
|
||||||
|
"""
|
||||||
|
and exists (
|
||||||
|
select 1
|
||||||
|
from eventhub.source_driver_identity identity
|
||||||
|
where identity.driver_id = event.driver_id
|
||||||
|
and identity.tenant_key = package.tenant_key
|
||||||
|
and identity.event_source_id = event.event_source_id
|
||||||
|
and identity.source_driver_entity_id = ?
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
);
|
||||||
params.add(driverSourceEntityId);
|
params.add(driverSourceEntityId);
|
||||||
}
|
}
|
||||||
if (driverCardNumber != null) {
|
if (driverCardNumber != null) {
|
||||||
|
|
@ -224,7 +262,18 @@ public class EventHubEventReadRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vehicleSourceEntityId != null) {
|
if (vehicleSourceEntityId != null) {
|
||||||
sql.append(" and vehicle.source_vehicle_entity_id = ?");
|
sql.append(
|
||||||
|
"""
|
||||||
|
and exists (
|
||||||
|
select 1
|
||||||
|
from eventhub.source_vehicle_identity identity
|
||||||
|
where identity.vehicle_id = event.vehicle_id
|
||||||
|
and identity.tenant_key = package.tenant_key
|
||||||
|
and identity.event_source_id = event.event_source_id
|
||||||
|
and identity.source_vehicle_entity_id = ?
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
);
|
||||||
params.add(vehicleSourceEntityId);
|
params.add(vehicleSourceEntityId);
|
||||||
}
|
}
|
||||||
if (vin != null) {
|
if (vin != null) {
|
||||||
|
|
@ -246,6 +295,17 @@ public class EventHubEventReadRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (registrationNumber == null && registrationNation != null) {
|
||||||
|
TachographNationRegistry.NationResolution registrationNationResolution =
|
||||||
|
TachographNationRegistry.resolve(registrationNation, null);
|
||||||
|
if (registrationNationResolution.numericCode() != null) {
|
||||||
|
sql.append(" and registration.nation_numeric_code = ?");
|
||||||
|
params.add(registrationNationResolution.numericCode());
|
||||||
|
} else {
|
||||||
|
sql.append(" and registration.nation = ?");
|
||||||
|
params.add(registrationNationResolution.legacyNation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sql.append(" order by event.occurred_at, event.event_domain, event.event_type, event.lifecycle, event.id");
|
sql.append(" order by event.occurred_at, event.event_domain, event.event_type, event.lifecycle, event.id");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package at.procon.eventhub.processing.dto;
|
||||||
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
|
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBackend;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBackend;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
||||||
|
import at.procon.eventhub.processing.model.UnifiedTachographSourceKind;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -15,6 +16,7 @@ public record UnifiedRuntimeProcessingApiRequest(
|
||||||
String tenantKey,
|
String tenantKey,
|
||||||
Set<UnifiedEventSourceFamily> sourceFamilies,
|
Set<UnifiedEventSourceFamily> sourceFamilies,
|
||||||
UnifiedRuntimeEventBackend eventBackend,
|
UnifiedRuntimeEventBackend eventBackend,
|
||||||
|
Set<UnifiedTachographSourceKind> tachographSourceKinds,
|
||||||
String driverKey,
|
String driverKey,
|
||||||
Set<String> driverKeys,
|
Set<String> driverKeys,
|
||||||
Boolean includeAllDrivers,
|
Boolean includeAllDrivers,
|
||||||
|
|
@ -38,6 +40,7 @@ public record UnifiedRuntimeProcessingApiRequest(
|
||||||
tenantKey,
|
tenantKey,
|
||||||
sourceFamilies,
|
sourceFamilies,
|
||||||
eventBackend,
|
eventBackend,
|
||||||
|
tachographSourceKinds,
|
||||||
driverKey,
|
driverKey,
|
||||||
driverKeys,
|
driverKeys,
|
||||||
includeAllDrivers != null && includeAllDrivers,
|
includeAllDrivers != null && includeAllDrivers,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import at.procon.eventhub.processing.model.UnifiedDiscoveredVehicleRef;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
||||||
import at.procon.eventhub.processing.service.RuntimeDriverVehicleEvidenceAttachmentService;
|
import at.procon.eventhub.processing.service.RuntimeDriverVehicleEvidenceAttachmentService;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
@ -258,18 +259,7 @@ public class VehicleEvidenceAttachmentModule implements RuntimeProcessingModule
|
||||||
}
|
}
|
||||||
|
|
||||||
private String driverKey(EventHubEventDto event) {
|
private String driverKey(EventHubEventDto event) {
|
||||||
if (event == null) {
|
return TachographRuntimeIdentityResolver.driverKey(event);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String rawDriverKey = text(rawPayload(event), "driverKey");
|
|
||||||
if (rawDriverKey != null) {
|
|
||||||
return rawDriverKey;
|
|
||||||
}
|
|
||||||
DriverRefDto driverRef = event.driverRef();
|
|
||||||
if (driverRef != null && driverRef.hasAnyReference()) {
|
|
||||||
return driverRef.stableKey();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonNode rawPayload(EventHubEventDto event) {
|
private JsonNode rawPayload(EventHubEventDto event) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import at.procon.eventhub.processing.eventprocessing.module.DriverWorkingTimeMod
|
||||||
import at.procon.eventhub.processing.eventprocessing.module.RuntimeProcessingModuleContext;
|
import at.procon.eventhub.processing.eventprocessing.module.RuntimeProcessingModuleContext;
|
||||||
import at.procon.eventhub.processing.eventprocessing.module.RuntimeProcessingModuleResult;
|
import at.procon.eventhub.processing.eventprocessing.module.RuntimeProcessingModuleResult;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -151,7 +152,7 @@ public final class DriverWorkingTimeEplEventMapper {
|
||||||
JsonNode raw = rawPayload(sourceEvent);
|
JsonNode raw = rawPayload(sourceEvent);
|
||||||
JsonNode attributes = attributes(sourceEvent);
|
JsonNode attributes = attributes(sourceEvent);
|
||||||
String intervalId = firstNonBlank(text(raw, "intervalId"), text(raw, "sourceRowId"), sourceEvent.externalSourceEventId());
|
String intervalId = firstNonBlank(text(raw, "intervalId"), text(raw, "sourceRowId"), sourceEvent.externalSourceEventId());
|
||||||
String driverKey = firstNonBlank(text(raw, "driverKey"), driverKey(sourceEvent));
|
String driverKey = TachographRuntimeIdentityResolver.driverKey(sourceEvent);
|
||||||
if (driverKey == null || intervalId == null) {
|
if (driverKey == null || intervalId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -169,8 +170,8 @@ public final class DriverWorkingTimeEplEventMapper {
|
||||||
event.put("cardSlot", firstNonBlank(text(raw, "cardSlot"), text(attributes, "cardSlot")));
|
event.put("cardSlot", firstNonBlank(text(raw, "cardSlot"), text(attributes, "cardSlot")));
|
||||||
event.put("cardStatus", firstNonBlank(text(raw, "cardStatus"), text(attributes, "cardStatus")));
|
event.put("cardStatus", firstNonBlank(text(raw, "cardStatus"), text(attributes, "cardStatus")));
|
||||||
event.put("drivingStatus", firstNonBlank(text(raw, "drivingStatus"), text(attributes, "drivingStatus")));
|
event.put("drivingStatus", firstNonBlank(text(raw, "drivingStatus"), text(attributes, "drivingStatus")));
|
||||||
event.put("registrationKey", firstNonBlank(text(raw, "registrationKey"), registrationKey(sourceEvent)));
|
event.put("registrationKey", TachographRuntimeIdentityResolver.registrationKey(sourceEvent));
|
||||||
event.put("vehicleKey", firstNonBlank(text(raw, "vehicleKey"), vehicleKey(sourceEvent)));
|
event.put("vehicleKey", TachographRuntimeIdentityResolver.vehicleKey(sourceEvent));
|
||||||
event.put("sourceKind", firstNonBlank(text(raw, "sourceKind"), sourceKind(sourceEvent)));
|
event.put("sourceKind", firstNonBlank(text(raw, "sourceKind"), sourceKind(sourceEvent)));
|
||||||
event.put("synthetic", booleanValue(raw, "synthetic", false));
|
event.put("synthetic", booleanValue(raw, "synthetic", false));
|
||||||
event.put("clippedToRequestedPeriod", booleanValue(raw, "clippedToRequestedPeriod", false));
|
event.put("clippedToRequestedPeriod", booleanValue(raw, "clippedToRequestedPeriod", false));
|
||||||
|
|
@ -192,7 +193,7 @@ public final class DriverWorkingTimeEplEventMapper {
|
||||||
}
|
}
|
||||||
JsonNode raw = rawPayload(sourceEvent);
|
JsonNode raw = rawPayload(sourceEvent);
|
||||||
String intervalId = firstNonBlank(text(raw, "intervalId"), text(raw, "sourceRowId"), sourceEvent.externalSourceEventId());
|
String intervalId = firstNonBlank(text(raw, "intervalId"), text(raw, "sourceRowId"), sourceEvent.externalSourceEventId());
|
||||||
String driverKey = firstNonBlank(text(raw, "driverKey"), driverKey(sourceEvent));
|
String driverKey = TachographRuntimeIdentityResolver.driverKey(sourceEvent);
|
||||||
if (driverKey == null || intervalId == null) {
|
if (driverKey == null || intervalId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -206,8 +207,8 @@ public final class DriverWorkingTimeEplEventMapper {
|
||||||
event.put("lifecycle", sourceEvent.lifecycle().name());
|
event.put("lifecycle", sourceEvent.lifecycle().name());
|
||||||
event.put("occurredAt", sourceEvent.occurredAt());
|
event.put("occurredAt", sourceEvent.occurredAt());
|
||||||
event.put("occurredAtEpochSecond", sourceEvent.occurredAt().toEpochSecond());
|
event.put("occurredAtEpochSecond", sourceEvent.occurredAt().toEpochSecond());
|
||||||
event.put("registrationKey", firstNonBlank(text(raw, "registrationKey"), registrationKey(sourceEvent)));
|
event.put("registrationKey", TachographRuntimeIdentityResolver.registrationKey(sourceEvent));
|
||||||
event.put("vehicleKey", firstNonBlank(text(raw, "vehicleKey"), vehicleKey(sourceEvent)));
|
event.put("vehicleKey", TachographRuntimeIdentityResolver.vehicleKey(sourceEvent));
|
||||||
event.put("sourceKind", firstNonBlank(text(raw, "sourceKind"), sourceKind(sourceEvent)));
|
event.put("sourceKind", firstNonBlank(text(raw, "sourceKind"), sourceKind(sourceEvent)));
|
||||||
event.put("odometerKm", odometerKm(sourceEvent, raw));
|
event.put("odometerKm", odometerKm(sourceEvent, raw));
|
||||||
return event;
|
return event;
|
||||||
|
|
@ -338,30 +339,6 @@ public final class DriverWorkingTimeEplEventMapper {
|
||||||
return new UUID(0L, 0L);
|
return new UUID(0L, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String driverKey(EventHubEventDto event) {
|
|
||||||
if (event.driverRef() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (event.driverRef().driverCard() != null && event.driverRef().driverCard().hasValue()) {
|
|
||||||
return event.driverRef().driverCard().stableKey();
|
|
||||||
}
|
|
||||||
return event.driverRef().sourceEntityId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String registrationKey(EventHubEventDto event) {
|
|
||||||
if (event.vehicleRef() == null || event.vehicleRef().vehicleRegistration() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return event.vehicleRef().vehicleRegistration().stableKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String vehicleKey(EventHubEventDto event) {
|
|
||||||
if (event.vehicleRef() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return firstNonBlank(event.vehicleRef().vin(), event.vehicleRef().sourceVehicleEntityId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String sourceKind(EventHubEventDto event) {
|
private static String sourceKind(EventHubEventDto event) {
|
||||||
return event.packageInfo() == null || event.packageInfo().eventSource() == null
|
return event.packageInfo() == null || event.packageInfo().eventSource() == null
|
||||||
? null
|
? null
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,7 @@ public class DriverWorkingTimeRuntimeProcessingPlan implements RuntimeProcessing
|
||||||
sourceSelection.tenantKey(),
|
sourceSelection.tenantKey(),
|
||||||
sourceSelection.sourceFamilies(),
|
sourceSelection.sourceFamilies(),
|
||||||
sourceSelection.eventBackend(),
|
sourceSelection.eventBackend(),
|
||||||
|
sourceSelection.tachographSourceKinds(),
|
||||||
sourceSelection.driverKey(),
|
sourceSelection.driverKey(),
|
||||||
driverKeys,
|
driverKeys,
|
||||||
includeAllDrivers,
|
includeAllDrivers,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import at.procon.eventhub.dto.EventLifecycle;
|
||||||
import at.procon.eventhub.dto.EventType;
|
import at.procon.eventhub.dto.EventType;
|
||||||
import at.procon.eventhub.dto.GeoPointDto;
|
import at.procon.eventhub.dto.GeoPointDto;
|
||||||
import at.procon.eventhub.dto.VehicleRefDto;
|
import at.procon.eventhub.dto.VehicleRefDto;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
@ -81,9 +82,9 @@ public class RuntimeSupportEvidenceNormalizer {
|
||||||
event.eventDomain() == null ? null : event.eventDomain().name(),
|
event.eventDomain() == null ? null : event.eventDomain().name(),
|
||||||
event.eventType() == null ? null : event.eventType().name(),
|
event.eventType() == null ? null : event.eventType().name(),
|
||||||
event.lifecycle() == null ? null : event.lifecycle().name(),
|
event.lifecycle() == null ? null : event.lifecycle().name(),
|
||||||
firstNonBlank(text(raw, "driverKey"), fallbackDriverKey, driverKey(event)),
|
firstNonBlank(TachographRuntimeIdentityResolver.driverKey(event), fallbackDriverKey),
|
||||||
firstNonBlank(text(raw, "vehicleKey"), vehicleKey(event)),
|
TachographRuntimeIdentityResolver.vehicleKey(event),
|
||||||
firstNonBlank(text(raw, "registrationKey"), registrationKey(event)),
|
TachographRuntimeIdentityResolver.registrationKey(event),
|
||||||
event.occurredAt(),
|
event.occurredAt(),
|
||||||
event.occurredAt() == null ? null : event.occurredAt().toEpochSecond(),
|
event.occurredAt() == null ? null : event.occurredAt().toEpochSecond(),
|
||||||
latitude,
|
latitude,
|
||||||
|
|
@ -287,53 +288,7 @@ public class RuntimeSupportEvidenceNormalizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonNode rawPayload(EventHubEventDto event) {
|
private JsonNode rawPayload(EventHubEventDto event) {
|
||||||
if (event == null || event.payload() == null || event.payload().isNull() || event.payload().isMissingNode()) {
|
return TachographRuntimeIdentityResolver.rawPayload(event);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
JsonNode raw = event.payload().get("raw");
|
|
||||||
return raw == null || raw.isNull() ? event.payload() : raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String driverKey(EventHubEventDto event) {
|
|
||||||
if (event == null || event.driverRef() == null || !event.driverRef().hasAnyReference()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return event.driverRef().stableKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String vehicleKey(EventHubEventDto event) {
|
|
||||||
JsonNode raw = rawPayload(event);
|
|
||||||
String rawVehicleKey = text(raw, "vehicleKey");
|
|
||||||
if (rawVehicleKey != null) {
|
|
||||||
return rawVehicleKey;
|
|
||||||
}
|
|
||||||
VehicleRefDto vehicleRef = event == null ? null : event.vehicleRef();
|
|
||||||
if (vehicleRef == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (vehicleRef.vin() != null) {
|
|
||||||
return vehicleRef.vin();
|
|
||||||
}
|
|
||||||
if (vehicleRef.sourceVehicleEntityId() != null) {
|
|
||||||
return vehicleRef.sourceVehicleEntityId();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String registrationKey(EventHubEventDto event) {
|
|
||||||
JsonNode raw = rawPayload(event);
|
|
||||||
String rawRegistrationKey = text(raw, "registrationKey");
|
|
||||||
if (rawRegistrationKey != null) {
|
|
||||||
return rawRegistrationKey;
|
|
||||||
}
|
|
||||||
VehicleRefDto vehicleRef = event == null ? null : event.vehicleRef();
|
|
||||||
if (vehicleRef == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (vehicleRef.vehicleRegistration() != null && vehicleRef.vehicleRegistration().hasValue()) {
|
|
||||||
return vehicleRef.vehicleRegistration().stableKey();
|
|
||||||
}
|
|
||||||
return vehicleRef.sourceRegistrationEntityId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String detailText(EventHubEventDto event, String field) {
|
private String detailText(EventHubEventDto event, String field) {
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,7 @@ public class RuntimeTachographParityValidationService {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
driverKeys,
|
driverKeys,
|
||||||
request.includeAllDriversOrDefault(),
|
request.includeAllDriversOrDefault(),
|
||||||
null,
|
null,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@ package at.procon.eventhub.processing.model;
|
||||||
|
|
||||||
import at.procon.eventhub.reference.DriverCardNumberNormalizer;
|
import at.procon.eventhub.reference.DriverCardNumberNormalizer;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public record UnifiedDriverEventsRequest(
|
public record UnifiedDriverEventsRequest(
|
||||||
UnifiedEventSourceFamily sourceFamily,
|
UnifiedEventSourceFamily sourceFamily,
|
||||||
|
List<String> sourceKinds,
|
||||||
UUID sessionId,
|
UUID sessionId,
|
||||||
String driverKey,
|
String driverKey,
|
||||||
String tenantKey,
|
String tenantKey,
|
||||||
|
|
@ -22,6 +24,7 @@ public record UnifiedDriverEventsRequest(
|
||||||
) {
|
) {
|
||||||
public UnifiedDriverEventsRequest {
|
public UnifiedDriverEventsRequest {
|
||||||
Objects.requireNonNull(sourceFamily, "sourceFamily must not be null");
|
Objects.requireNonNull(sourceFamily, "sourceFamily must not be null");
|
||||||
|
sourceKinds = sourceKinds == null ? List.of() : List.copyOf(sourceKinds);
|
||||||
driverKey = normalize(driverKey);
|
driverKey = normalize(driverKey);
|
||||||
tenantKey = normalize(tenantKey);
|
tenantKey = normalize(tenantKey);
|
||||||
driverSourceEntityId = normalize(driverSourceEntityId);
|
driverSourceEntityId = normalize(driverSourceEntityId);
|
||||||
|
|
@ -59,6 +62,7 @@ public record UnifiedDriverEventsRequest(
|
||||||
) {
|
) {
|
||||||
return new UnifiedDriverEventsRequest(
|
return new UnifiedDriverEventsRequest(
|
||||||
UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION,
|
UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION,
|
||||||
|
List.of(),
|
||||||
sessionId,
|
sessionId,
|
||||||
driverKey,
|
driverKey,
|
||||||
null,
|
null,
|
||||||
|
|
@ -81,9 +85,30 @@ public record UnifiedDriverEventsRequest(
|
||||||
String driverCardNumber,
|
String driverCardNumber,
|
||||||
OffsetDateTime occurredFrom,
|
OffsetDateTime occurredFrom,
|
||||||
OffsetDateTime occurredTo
|
OffsetDateTime occurredTo
|
||||||
|
) {
|
||||||
|
return forTachographDbDriver(
|
||||||
|
tenantKey,
|
||||||
|
driverSourceEntityId,
|
||||||
|
driverCardNation,
|
||||||
|
driverCardNumber,
|
||||||
|
occurredFrom,
|
||||||
|
occurredTo,
|
||||||
|
List.of()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnifiedDriverEventsRequest forTachographDbDriver(
|
||||||
|
String tenantKey,
|
||||||
|
String driverSourceEntityId,
|
||||||
|
String driverCardNation,
|
||||||
|
String driverCardNumber,
|
||||||
|
OffsetDateTime occurredFrom,
|
||||||
|
OffsetDateTime occurredTo,
|
||||||
|
List<String> sourceKinds
|
||||||
) {
|
) {
|
||||||
return new UnifiedDriverEventsRequest(
|
return new UnifiedDriverEventsRequest(
|
||||||
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
||||||
|
sourceKinds,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
tenantKey,
|
tenantKey,
|
||||||
|
|
@ -110,6 +135,7 @@ public record UnifiedDriverEventsRequest(
|
||||||
) {
|
) {
|
||||||
return new UnifiedDriverEventsRequest(
|
return new UnifiedDriverEventsRequest(
|
||||||
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
||||||
|
List.of(),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
tenantKey,
|
tenantKey,
|
||||||
|
|
@ -135,6 +161,7 @@ public record UnifiedDriverEventsRequest(
|
||||||
) {
|
) {
|
||||||
return new UnifiedDriverEventsRequest(
|
return new UnifiedDriverEventsRequest(
|
||||||
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
||||||
|
List.of(),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
tenantKey,
|
tenantKey,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package at.procon.eventhub.processing.model;
|
||||||
import at.procon.eventhub.reference.DriverCardNumberNormalizer;
|
import at.procon.eventhub.reference.DriverCardNumberNormalizer;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -15,6 +16,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
String tenantKey,
|
String tenantKey,
|
||||||
Set<UnifiedEventSourceFamily> sourceFamilies,
|
Set<UnifiedEventSourceFamily> sourceFamilies,
|
||||||
UnifiedRuntimeEventBackend eventBackend,
|
UnifiedRuntimeEventBackend eventBackend,
|
||||||
|
Set<UnifiedTachographSourceKind> tachographSourceKinds,
|
||||||
String driverKey,
|
String driverKey,
|
||||||
Set<String> driverKeys,
|
Set<String> driverKeys,
|
||||||
boolean includeAllDrivers,
|
boolean includeAllDrivers,
|
||||||
|
|
@ -34,6 +36,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
}
|
}
|
||||||
sourceFamilies = Set.copyOf(sourceFamilies);
|
sourceFamilies = Set.copyOf(sourceFamilies);
|
||||||
eventBackend = eventBackend == null ? UnifiedRuntimeEventBackend.SOURCE_DB : eventBackend;
|
eventBackend = eventBackend == null ? UnifiedRuntimeEventBackend.SOURCE_DB : eventBackend;
|
||||||
|
tachographSourceKinds = normalizeTachographSourceKinds(tachographSourceKinds);
|
||||||
sessionIds = normalizeSessionIds(sessionId, sessionIds);
|
sessionIds = normalizeSessionIds(sessionId, sessionIds);
|
||||||
if (sessionId == null && !sessionIds.isEmpty()) {
|
if (sessionId == null && !sessionIds.isEmpty()) {
|
||||||
sessionId = sessionIds.get(0);
|
sessionId = sessionIds.get(0);
|
||||||
|
|
@ -164,6 +167,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
sourceFamilies,
|
sourceFamilies,
|
||||||
eventBackend,
|
eventBackend,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
@ -197,6 +201,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
sourceFamilies,
|
sourceFamilies,
|
||||||
UnifiedRuntimeEventBackend.EVENTHUB_DB,
|
UnifiedRuntimeEventBackend.EVENTHUB_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
@ -226,6 +231,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
null,
|
null,
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
|
null,
|
||||||
driverKey,
|
driverKey,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -256,6 +262,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
null,
|
null,
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
|
null,
|
||||||
driverKey,
|
driverKey,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -286,6 +293,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
null,
|
null,
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
|
null,
|
||||||
driverKey,
|
driverKey,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -328,6 +336,7 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
tenantKey,
|
tenantKey,
|
||||||
sourceFamilies,
|
sourceFamilies,
|
||||||
eventBackend,
|
eventBackend,
|
||||||
|
tachographSourceKinds,
|
||||||
value,
|
value,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -347,6 +356,23 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
return includeAllDrivers || driverKeys.size() > 1 || (driverKey == null && !driverKeys.isEmpty());
|
return includeAllDrivers || driverKeys.size() > 1 || (driverKey == null && !driverKeys.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean includesTachographSourceKind(String sourceKind) {
|
||||||
|
if (sourceKind == null || sourceKind.isBlank()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return tachographSourceKinds.contains(UnifiedTachographSourceKind.valueOf(sourceKind.trim().toUpperCase()));
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> tachographSourceKindNames() {
|
||||||
|
return tachographSourceKinds.stream()
|
||||||
|
.map(UnifiedTachographSourceKind::name)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
private static Set<String> normalizeStrings(Set<String> values) {
|
private static Set<String> normalizeStrings(Set<String> values) {
|
||||||
if (values == null || values.isEmpty()) {
|
if (values == null || values.isEmpty()) {
|
||||||
return Set.of();
|
return Set.of();
|
||||||
|
|
@ -361,6 +387,15 @@ public record UnifiedRuntimeProcessingRequest(
|
||||||
return Set.copyOf(normalized);
|
return Set.copyOf(normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Set<UnifiedTachographSourceKind> normalizeTachographSourceKinds(
|
||||||
|
Set<UnifiedTachographSourceKind> values
|
||||||
|
) {
|
||||||
|
if (values == null || values.isEmpty()) {
|
||||||
|
return Set.copyOf(Arrays.asList(UnifiedTachographSourceKind.values()));
|
||||||
|
}
|
||||||
|
return Set.copyOf(values);
|
||||||
|
}
|
||||||
|
|
||||||
private static String normalize(String value) {
|
private static String normalize(String value) {
|
||||||
return value == null || value.isBlank() ? null : value.trim();
|
return value == null || value.isBlank() ? null : value.trim();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package at.procon.eventhub.processing.model;
|
||||||
|
|
||||||
|
public enum UnifiedTachographSourceKind {
|
||||||
|
DRIVER_CARD,
|
||||||
|
VEHICLE_UNIT
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
package at.procon.eventhub.processing.model;
|
package at.procon.eventhub.processing.model;
|
||||||
|
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public record UnifiedVehicleEventsRequest(
|
public record UnifiedVehicleEventsRequest(
|
||||||
UnifiedEventSourceFamily sourceFamily,
|
UnifiedEventSourceFamily sourceFamily,
|
||||||
|
List<String> sourceKinds,
|
||||||
UUID sessionId,
|
UUID sessionId,
|
||||||
String tenantKey,
|
String tenantKey,
|
||||||
String vehicleSourceEntityId,
|
String vehicleSourceEntityId,
|
||||||
|
|
@ -17,6 +19,7 @@ public record UnifiedVehicleEventsRequest(
|
||||||
) {
|
) {
|
||||||
public UnifiedVehicleEventsRequest {
|
public UnifiedVehicleEventsRequest {
|
||||||
Objects.requireNonNull(sourceFamily, "sourceFamily must not be null");
|
Objects.requireNonNull(sourceFamily, "sourceFamily must not be null");
|
||||||
|
sourceKinds = sourceKinds == null ? List.of() : List.copyOf(sourceKinds);
|
||||||
tenantKey = normalize(tenantKey);
|
tenantKey = normalize(tenantKey);
|
||||||
vehicleSourceEntityId = normalize(vehicleSourceEntityId);
|
vehicleSourceEntityId = normalize(vehicleSourceEntityId);
|
||||||
vin = normalizeUpper(vin);
|
vin = normalizeUpper(vin);
|
||||||
|
|
@ -46,6 +49,7 @@ public record UnifiedVehicleEventsRequest(
|
||||||
) {
|
) {
|
||||||
return new UnifiedVehicleEventsRequest(
|
return new UnifiedVehicleEventsRequest(
|
||||||
UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION,
|
UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION,
|
||||||
|
List.of(),
|
||||||
sessionId,
|
sessionId,
|
||||||
null,
|
null,
|
||||||
vehicleSourceEntityId,
|
vehicleSourceEntityId,
|
||||||
|
|
@ -65,9 +69,32 @@ public record UnifiedVehicleEventsRequest(
|
||||||
String registrationNumber,
|
String registrationNumber,
|
||||||
OffsetDateTime occurredFrom,
|
OffsetDateTime occurredFrom,
|
||||||
OffsetDateTime occurredTo
|
OffsetDateTime occurredTo
|
||||||
|
) {
|
||||||
|
return forTachographDb(
|
||||||
|
tenantKey,
|
||||||
|
vehicleSourceEntityId,
|
||||||
|
vin,
|
||||||
|
registrationNation,
|
||||||
|
registrationNumber,
|
||||||
|
occurredFrom,
|
||||||
|
occurredTo,
|
||||||
|
List.of()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnifiedVehicleEventsRequest forTachographDb(
|
||||||
|
String tenantKey,
|
||||||
|
String vehicleSourceEntityId,
|
||||||
|
String vin,
|
||||||
|
String registrationNation,
|
||||||
|
String registrationNumber,
|
||||||
|
OffsetDateTime occurredFrom,
|
||||||
|
OffsetDateTime occurredTo,
|
||||||
|
List<String> sourceKinds
|
||||||
) {
|
) {
|
||||||
return new UnifiedVehicleEventsRequest(
|
return new UnifiedVehicleEventsRequest(
|
||||||
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
||||||
|
sourceKinds,
|
||||||
null,
|
null,
|
||||||
tenantKey,
|
tenantKey,
|
||||||
vehicleSourceEntityId,
|
vehicleSourceEntityId,
|
||||||
|
|
@ -90,6 +117,7 @@ public record UnifiedVehicleEventsRequest(
|
||||||
) {
|
) {
|
||||||
return new UnifiedVehicleEventsRequest(
|
return new UnifiedVehicleEventsRequest(
|
||||||
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
||||||
|
List.of(),
|
||||||
null,
|
null,
|
||||||
tenantKey,
|
tenantKey,
|
||||||
vehicleSourceEntityId,
|
vehicleSourceEntityId,
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,8 @@ public class EventHubRuntimeEventLoader implements RuntimeDriverEventLoader, Run
|
||||||
request.driverCardNation(),
|
request.driverCardNation(),
|
||||||
request.driverCardNumber(),
|
request.driverCardNumber(),
|
||||||
request.occurredFrom(),
|
request.occurredFrom(),
|
||||||
request.occurredTo()
|
request.occurredTo(),
|
||||||
|
request.tachographSourceKindNames()
|
||||||
);
|
);
|
||||||
case YELLOWFOX_DB -> UnifiedDriverEventsRequest.forYellowFoxDbDriver(
|
case YELLOWFOX_DB -> UnifiedDriverEventsRequest.forYellowFoxDbDriver(
|
||||||
request.tenantKey(),
|
request.tenantKey(),
|
||||||
|
|
@ -97,7 +98,8 @@ public class EventHubRuntimeEventLoader implements RuntimeDriverEventLoader, Run
|
||||||
vehicleRef.registrationNation(),
|
vehicleRef.registrationNation(),
|
||||||
vehicleRef.registrationNumber(),
|
vehicleRef.registrationNumber(),
|
||||||
request.vehicleOccurredFrom(),
|
request.vehicleOccurredFrom(),
|
||||||
request.vehicleOccurredTo()
|
request.vehicleOccurredTo(),
|
||||||
|
request.tachographSourceKindNames()
|
||||||
);
|
);
|
||||||
case YELLOWFOX_DB -> UnifiedVehicleEventsRequest.forYellowFoxDb(
|
case YELLOWFOX_DB -> UnifiedVehicleEventsRequest.forYellowFoxDb(
|
||||||
request.tenantKey(),
|
request.tenantKey(),
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import at.procon.eventhub.processing.dto.RuntimeVehicleUsageIntervalDebugDto;
|
||||||
import at.procon.eventhub.processing.eventprocessing.partition.RuntimeEventScopeClassifier;
|
import at.procon.eventhub.processing.eventprocessing.partition.RuntimeEventScopeClassifier;
|
||||||
import at.procon.eventhub.processing.eventprocessing.partition.RuntimeEventScopeType;
|
import at.procon.eventhub.processing.eventprocessing.partition.RuntimeEventScopeType;
|
||||||
import at.procon.eventhub.processing.model.RuntimeDriverVehicleEvidenceAttachmentResult;
|
import at.procon.eventhub.processing.model.RuntimeDriverVehicleEvidenceAttachmentResult;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import at.procon.eventhub.tachographfilesession.model.ResolvedDriverTimeline;
|
import at.procon.eventhub.tachographfilesession.model.ResolvedDriverTimeline;
|
||||||
import at.procon.eventhub.tachographfilesession.model.ResolvedVehicleUsageInterval;
|
import at.procon.eventhub.tachographfilesession.model.ResolvedVehicleUsageInterval;
|
||||||
import at.procon.eventhub.tachographfilesession.service.TachographDriverWorkingTimeAdapter;
|
import at.procon.eventhub.tachographfilesession.service.TachographDriverWorkingTimeAdapter;
|
||||||
|
|
@ -275,22 +276,15 @@ public class RuntimeDriverVehicleEvidenceAttachmentService {
|
||||||
|
|
||||||
private Set<String> vehicleKeys(EventHubEventDto event) {
|
private Set<String> vehicleKeys(EventHubEventDto event) {
|
||||||
LinkedHashSet<String> result = new LinkedHashSet<>();
|
LinkedHashSet<String> result = new LinkedHashSet<>();
|
||||||
JsonNode raw = rawPayload(event);
|
String vehicleKey = TachographRuntimeIdentityResolver.vehicleKey(event);
|
||||||
add(result, text(raw, "vehicleKey"));
|
String registrationKey = TachographRuntimeIdentityResolver.registrationKey(event);
|
||||||
add(result, text(raw, "registrationKey"));
|
add(result, vehicleKey);
|
||||||
VehicleRefDto vehicleRef = event.vehicleRef();
|
|
||||||
if (vehicleRef != null) {
|
|
||||||
add(result, vehicleRef.sourceVehicleEntityId());
|
|
||||||
add(result, vehicleRef.sourceRegistrationEntityId());
|
|
||||||
add(result, vehicleRef.vin());
|
|
||||||
if (vehicleRef.vin() != null) {
|
|
||||||
add(result, "VIN:" + vehicleRef.vin());
|
|
||||||
}
|
|
||||||
if (vehicleRef.vehicleRegistration() != null) {
|
|
||||||
String registrationKey = vehicleRef.vehicleRegistration().stableKey();
|
|
||||||
add(result, registrationKey);
|
add(result, registrationKey);
|
||||||
add(result, "VR:" + registrationKey);
|
if (vehicleKey != null) {
|
||||||
|
add(result, "VIN:" + vehicleKey);
|
||||||
}
|
}
|
||||||
|
if (registrationKey != null) {
|
||||||
|
add(result, "VR:" + registrationKey);
|
||||||
}
|
}
|
||||||
return Set.copyOf(result);
|
return Set.copyOf(result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package at.procon.eventhub.processing.service;
|
package at.procon.eventhub.processing.service;
|
||||||
|
|
||||||
import at.procon.eventhub.dto.DriverRefDto;
|
|
||||||
import at.procon.eventhub.dto.EventHubEventDto;
|
import at.procon.eventhub.dto.EventHubEventDto;
|
||||||
import at.procon.eventhub.dto.VehicleRefDto;
|
import at.procon.eventhub.dto.VehicleRefDto;
|
||||||
import at.procon.eventhub.processing.dto.RuntimeDriverPartitionDebugDto;
|
import at.procon.eventhub.processing.dto.RuntimeDriverPartitionDebugDto;
|
||||||
|
|
@ -11,6 +10,7 @@ import at.procon.eventhub.processing.model.UnifiedDiscoveredVehicleRef;
|
||||||
import at.procon.eventhub.processing.model.RuntimeDriverVehicleEvidenceAttachmentResult;
|
import at.procon.eventhub.processing.model.RuntimeDriverVehicleEvidenceAttachmentResult;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
@ -282,18 +282,7 @@ public class RuntimeDriverWorkingTimeScopeProcessingService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String driverKey(EventHubEventDto event) {
|
private String driverKey(EventHubEventDto event) {
|
||||||
if (event == null) {
|
return TachographRuntimeIdentityResolver.driverKey(event);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String rawDriverKey = text(rawPayload(event), "driverKey");
|
|
||||||
if (rawDriverKey != null) {
|
|
||||||
return rawDriverKey;
|
|
||||||
}
|
|
||||||
DriverRefDto driverRef = event.driverRef();
|
|
||||||
if (driverRef != null && driverRef.hasAnyReference()) {
|
|
||||||
return driverRef.stableKey();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonNode rawPayload(EventHubEventDto event) {
|
private JsonNode rawPayload(EventHubEventDto event) {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.StreamUtils;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ConditionalOnBean(name = "tachographNamedParameterJdbcTemplate")
|
|
||||||
@ConditionalOnExpression("T(org.springframework.util.StringUtils).hasText('${eventhub.tachograph.datasource.jdbc-url:}')")
|
@ConditionalOnExpression("T(org.springframework.util.StringUtils).hasText('${eventhub.tachograph.datasource.jdbc-url:}')")
|
||||||
public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader, RuntimeVehicleEventLoader {
|
public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader, RuntimeVehicleEventLoader {
|
||||||
|
|
||||||
|
|
@ -64,7 +63,7 @@ public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader,
|
||||||
@Override
|
@Override
|
||||||
public List<EventHubEventDto> loadDriverEvents(UnifiedRuntimeProcessingRequest request) {
|
public List<EventHubEventDto> loadDriverEvents(UnifiedRuntimeProcessingRequest request) {
|
||||||
List<EventHubEventDto> result = new ArrayList<>();
|
List<EventHubEventDto> result = new ArrayList<>();
|
||||||
for (ExtractionDefinition<TachographImportRequest> definition : driverDefinitions()) {
|
for (ExtractionDefinition<TachographImportRequest> definition : driverDefinitions(request)) {
|
||||||
result.addAll(queryDefinition(
|
result.addAll(queryDefinition(
|
||||||
definition,
|
definition,
|
||||||
request,
|
request,
|
||||||
|
|
@ -74,6 +73,7 @@ public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return List.copyOf(result);
|
return List.copyOf(result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -82,7 +82,7 @@ public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader,
|
||||||
UnifiedDiscoveredVehicleRef vehicleRef
|
UnifiedDiscoveredVehicleRef vehicleRef
|
||||||
) {
|
) {
|
||||||
List<EventHubEventDto> result = new ArrayList<>();
|
List<EventHubEventDto> result = new ArrayList<>();
|
||||||
for (ExtractionDefinition<TachographImportRequest> definition : vehicleDefinitions()) {
|
for (ExtractionDefinition<TachographImportRequest> definition : vehicleDefinitions(request)) {
|
||||||
result.addAll(queryDefinition(
|
result.addAll(queryDefinition(
|
||||||
definition,
|
definition,
|
||||||
request,
|
request,
|
||||||
|
|
@ -116,15 +116,21 @@ public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader,
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ExtractionDefinition<TachographImportRequest>> driverDefinitions() {
|
private List<ExtractionDefinition<TachographImportRequest>> driverDefinitions(
|
||||||
|
UnifiedRuntimeProcessingRequest request
|
||||||
|
) {
|
||||||
return definitionRegistry.definitions().stream()
|
return definitionRegistry.definitions().stream()
|
||||||
.filter(definition -> !"VEHICLE".equals(definition.entityAxis()))
|
.filter(definition -> !"VEHICLE".equals(definition.entityAxis()))
|
||||||
|
.filter(definition -> request.includesTachographSourceKind(definition.sourceKind()))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ExtractionDefinition<TachographImportRequest>> vehicleDefinitions() {
|
private List<ExtractionDefinition<TachographImportRequest>> vehicleDefinitions(
|
||||||
|
UnifiedRuntimeProcessingRequest request
|
||||||
|
) {
|
||||||
return definitionRegistry.definitions().stream()
|
return definitionRegistry.definitions().stream()
|
||||||
.filter(definition -> !"DRIVER".equals(definition.entityAxis()))
|
.filter(definition -> !"DRIVER".equals(definition.entityAxis()))
|
||||||
|
.filter(definition -> request.includesTachographSourceKind(definition.sourceKind()))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,33 +220,31 @@ public class TachographDbRuntimeEventLoader implements RuntimeDriverEventLoader,
|
||||||
UnifiedRuntimeProcessingRequest request,
|
UnifiedRuntimeProcessingRequest request,
|
||||||
UnifiedDiscoveredVehicleRef vehicleRef
|
UnifiedDiscoveredVehicleRef vehicleRef
|
||||||
) {
|
) {
|
||||||
StringBuilder sql = new StringBuilder("select * from (");
|
StringBuilder sql = new StringBuilder(baseSql.stripTrailing());
|
||||||
sql.append(baseSql);
|
|
||||||
sql.append("\n) runtime where 1 = 1");
|
|
||||||
if (request.driverSourceEntityId() != null) {
|
if (request.driverSourceEntityId() != null) {
|
||||||
sql.append("\n and runtime.driver_source_entity_id = :driverSourceEntityId");
|
sql.append("\n and extracted.driver_source_entity_id = :driverSourceEntityId");
|
||||||
}
|
}
|
||||||
if (request.driverCardNumber() != null) {
|
if (request.driverCardNumber() != null) {
|
||||||
sql.append("\n and runtime.driver_card_number = :driverCardNumber");
|
sql.append("\n and extracted.driver_card_number = :driverCardNumber");
|
||||||
if (request.driverCardNation() != null) {
|
if (request.driverCardNation() != null) {
|
||||||
sql.append("\n and runtime.driver_card_nation = :driverCardNation");
|
sql.append("\n and extracted.driver_card_nation = :driverCardNation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vehicleRef != null) {
|
if (vehicleRef != null) {
|
||||||
if (vehicleRef.sourceVehicleEntityId() != null) {
|
if (vehicleRef.sourceVehicleEntityId() != null) {
|
||||||
sql.append("\n and runtime.vehicle_source_entity_id = :vehicleSourceEntityId");
|
sql.append("\n and extracted.vehicle_source_entity_id = :vehicleSourceEntityId");
|
||||||
}
|
}
|
||||||
if (vehicleRef.vin() != null) {
|
if (vehicleRef.vin() != null) {
|
||||||
sql.append("\n and runtime.vehicle_vin = :vehicleVin");
|
sql.append("\n and extracted.vehicle_vin = :vehicleVin");
|
||||||
}
|
}
|
||||||
if (vehicleRef.registrationNumber() != null) {
|
if (vehicleRef.registrationNumber() != null) {
|
||||||
sql.append("\n and runtime.vehicle_registration_number = :vehicleRegistrationNumber");
|
sql.append("\n and extracted.vehicle_registration_number = :vehicleRegistrationNumber");
|
||||||
if (vehicleRef.registrationNation() != null) {
|
if (vehicleRef.registrationNation() != null) {
|
||||||
sql.append("\n and runtime.vehicle_registration_nation = :vehicleRegistrationNation");
|
sql.append("\n and extracted.vehicle_registration_nation = :vehicleRegistrationNation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sql.append("\norder by runtime.occurred_at, runtime.external_source_event_id");
|
sql.append("\norder by extracted.occurred_at, extracted.external_source_event_id");
|
||||||
return sql.toString();
|
return sql.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public class TachographDbUnifiedDriverEventSource implements UnifiedDriverEventS
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<EventHubEventDto> loadDriverEvents(UnifiedDriverEventsRequest request) {
|
public List<EventHubEventDto> loadDriverEvents(UnifiedDriverEventsRequest request) {
|
||||||
return repository.findEvents(request, "TACHOGRAPH", SOURCE_KINDS);
|
List<String> sourceKinds = request.sourceKinds().isEmpty() ? SOURCE_KINDS : request.sourceKinds();
|
||||||
|
return repository.findEvents(request, "TACHOGRAPH", sourceKinds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public class TachographDbUnifiedVehicleEventSource implements UnifiedVehicleEven
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request) {
|
public List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request) {
|
||||||
return repository.findEventsByVehicle(request, "TACHOGRAPH", SOURCE_KINDS);
|
List<String> sourceKinds = request.sourceKinds().isEmpty() ? SOURCE_KINDS : request.sourceKinds();
|
||||||
|
return repository.findEventsByVehicle(request, "TACHOGRAPH", sourceKinds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import at.procon.eventhub.dto.EventDomain;
|
||||||
import at.procon.eventhub.dto.EventHubEventDto;
|
import at.procon.eventhub.dto.EventHubEventDto;
|
||||||
import at.procon.eventhub.dto.EventLifecycle;
|
import at.procon.eventhub.dto.EventLifecycle;
|
||||||
import at.procon.eventhub.dto.EventType;
|
import at.procon.eventhub.dto.EventType;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import at.procon.eventhub.tachographfilesession.model.ExtractedSupportEvent;
|
import at.procon.eventhub.tachographfilesession.model.ExtractedSupportEvent;
|
||||||
import at.procon.eventhub.tachographfilesession.model.ExtractionWarning;
|
import at.procon.eventhub.tachographfilesession.model.ExtractionWarning;
|
||||||
import at.procon.eventhub.tachographfilesession.model.ResolvedActivityInterval;
|
import at.procon.eventhub.tachographfilesession.model.ResolvedActivityInterval;
|
||||||
|
|
@ -136,14 +137,14 @@ public class UnifiedEventTimelineReconstructor {
|
||||||
BigDecimal longitude = event.position() == null ? null : event.position().longitude();
|
BigDecimal longitude = event.position() == null ? null : event.position().longitude();
|
||||||
result.add(new ExtractedSupportEvent(
|
result.add(new ExtractedSupportEvent(
|
||||||
eventId,
|
eventId,
|
||||||
text(raw, "driverKey"),
|
TachographRuntimeIdentityResolver.driverKey(event),
|
||||||
event.occurredAt(),
|
event.occurredAt(),
|
||||||
event.eventDomain().name(),
|
event.eventDomain().name(),
|
||||||
text(raw, "supportEventType") == null ? event.eventType().name() : text(raw, "supportEventType"),
|
text(raw, "supportEventType") == null ? event.eventType().name() : text(raw, "supportEventType"),
|
||||||
event.lifecycle().name(),
|
event.lifecycle().name(),
|
||||||
text(raw, "slot"),
|
text(raw, "slot"),
|
||||||
text(raw, "registrationKey"),
|
TachographRuntimeIdentityResolver.registrationKey(event),
|
||||||
text(raw, "vehicleKey"),
|
TachographRuntimeIdentityResolver.vehicleKey(event),
|
||||||
firstNonBlank(text(raw, "country"), detailText(event, "country")),
|
firstNonBlank(text(raw, "country"), detailText(event, "country")),
|
||||||
text(raw, "region"),
|
text(raw, "region"),
|
||||||
firstNonBlank(text(raw, "countryFrom"), detailText(event, "countryFrom")),
|
firstNonBlank(text(raw, "countryFrom"), detailText(event, "countryFrom")),
|
||||||
|
|
@ -381,8 +382,8 @@ public class UnifiedEventTimelineReconstructor {
|
||||||
detailText(sample, "cardSlot"),
|
detailText(sample, "cardSlot"),
|
||||||
detailText(sample, "cardStatus"),
|
detailText(sample, "cardStatus"),
|
||||||
detailText(sample, "drivingStatus"),
|
detailText(sample, "drivingStatus"),
|
||||||
text(raw, "registrationKey"),
|
TachographRuntimeIdentityResolver.registrationKey(sample),
|
||||||
text(raw, "vehicleKey"),
|
TachographRuntimeIdentityResolver.vehicleKey(sample),
|
||||||
text(raw, "sourceKind"),
|
text(raw, "sourceKind"),
|
||||||
stringList(raw, "sourceRowIds"),
|
stringList(raw, "sourceRowIds"),
|
||||||
booleanValue(raw, "synthetic"),
|
booleanValue(raw, "synthetic"),
|
||||||
|
|
@ -400,6 +401,7 @@ public class UnifiedEventTimelineReconstructor {
|
||||||
private OffsetDateTime endedAt;
|
private OffsetDateTime endedAt;
|
||||||
private Long odometerBeginKm;
|
private Long odometerBeginKm;
|
||||||
private Long odometerEndKm;
|
private Long odometerEndKm;
|
||||||
|
private EventHubEventDto sample;
|
||||||
private JsonNode raw;
|
private JsonNode raw;
|
||||||
|
|
||||||
private VehicleUsageAccumulator(UUID sessionId, String driverKey, String intervalId) {
|
private VehicleUsageAccumulator(UUID sessionId, String driverKey, String intervalId) {
|
||||||
|
|
@ -409,6 +411,9 @@ public class UnifiedEventTimelineReconstructor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void accept(EventHubEventDto event, JsonNode raw) {
|
private void accept(EventHubEventDto event, JsonNode raw) {
|
||||||
|
if (sample == null) {
|
||||||
|
sample = event;
|
||||||
|
}
|
||||||
if (this.raw == null) {
|
if (this.raw == null) {
|
||||||
this.raw = raw;
|
this.raw = raw;
|
||||||
}
|
}
|
||||||
|
|
@ -433,8 +438,8 @@ public class UnifiedEventTimelineReconstructor {
|
||||||
endedAt,
|
endedAt,
|
||||||
odometerBeginKm,
|
odometerBeginKm,
|
||||||
odometerEndKm,
|
odometerEndKm,
|
||||||
text(raw, "registrationKey"),
|
sample == null ? null : TachographRuntimeIdentityResolver.registrationKey(sample),
|
||||||
text(raw, "vehicleKey"),
|
sample == null ? null : TachographRuntimeIdentityResolver.vehicleKey(sample),
|
||||||
text(raw, "sourceKind"),
|
text(raw, "sourceKind"),
|
||||||
stringList(raw, "sourceRowIds")
|
stringList(raw, "sourceRowIds")
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import at.procon.eventhub.tachographfilesession.model.TachographEsperPotentialIn
|
||||||
import at.procon.eventhub.tachographfilesession.model.TachographEsperSupportGeoEvent;
|
import at.procon.eventhub.tachographfilesession.model.TachographEsperSupportGeoEvent;
|
||||||
import at.procon.eventhub.tachographfilesession.model.TachographEsperVehicleUsageIntervalEvent;
|
import at.procon.eventhub.tachographfilesession.model.TachographEsperVehicleUsageIntervalEvent;
|
||||||
import at.procon.eventhub.tachographfilesession.model.TachographEsperVuCardAbsentIntervalEvent;
|
import at.procon.eventhub.tachographfilesession.model.TachographEsperVuCardAbsentIntervalEvent;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
|
|
@ -234,22 +235,7 @@ public class UnifiedRuntimeDerivedProjectionService {
|
||||||
UnifiedRuntimeProcessingRequest request,
|
UnifiedRuntimeProcessingRequest request,
|
||||||
List<EventHubEventDto> events
|
List<EventHubEventDto> events
|
||||||
) {
|
) {
|
||||||
if (request.driverKey() != null) {
|
return TachographRuntimeIdentityResolver.requestDriverKey(request, events);
|
||||||
return request.driverKey();
|
|
||||||
}
|
|
||||||
if (request.driverSourceEntityId() != null) {
|
|
||||||
return request.driverSourceEntityId();
|
|
||||||
}
|
|
||||||
for (EventHubEventDto event : events) {
|
|
||||||
DriverRefDto driverRef = event.driverRef();
|
|
||||||
if (driverRef != null && driverRef.hasAnyReference()) {
|
|
||||||
return driverRef.stableKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request.driverCardNation() != null && request.driverCardNumber() != null) {
|
|
||||||
return request.driverCardNation() + ":" + request.driverCardNumber();
|
|
||||||
}
|
|
||||||
return request.driverCardNumber();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package at.procon.eventhub.processing.service;
|
package at.procon.eventhub.processing.service;
|
||||||
|
|
||||||
import at.procon.eventhub.dto.DriverRefDto;
|
|
||||||
import at.procon.eventhub.dto.EventHubEventDto;
|
import at.procon.eventhub.dto.EventHubEventDto;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
|
||||||
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
||||||
|
import at.procon.eventhub.processing.support.TachographRuntimeIdentityResolver;
|
||||||
import at.procon.eventhub.tachographfilesession.model.ResolvedDriverTimeline;
|
import at.procon.eventhub.tachographfilesession.model.ResolvedDriverTimeline;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -35,21 +35,6 @@ public class UnifiedRuntimeDriverTimelineService {
|
||||||
UnifiedRuntimeProcessingRequest request,
|
UnifiedRuntimeProcessingRequest request,
|
||||||
List<EventHubEventDto> events
|
List<EventHubEventDto> events
|
||||||
) {
|
) {
|
||||||
if (request.driverKey() != null) {
|
return TachographRuntimeIdentityResolver.requestDriverKey(request, events);
|
||||||
return request.driverKey();
|
|
||||||
}
|
|
||||||
if (request.driverSourceEntityId() != null) {
|
|
||||||
return request.driverSourceEntityId();
|
|
||||||
}
|
|
||||||
for (EventHubEventDto event : events) {
|
|
||||||
DriverRefDto driverRef = event.driverRef();
|
|
||||||
if (driverRef != null && driverRef.hasAnyReference()) {
|
|
||||||
return driverRef.stableKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request.driverCardNation() != null && request.driverCardNumber() != null) {
|
|
||||||
return request.driverCardNation() + ":" + request.driverCardNumber();
|
|
||||||
}
|
|
||||||
return request.driverCardNumber();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
package at.procon.eventhub.processing.support;
|
||||||
|
|
||||||
|
import at.procon.eventhub.dto.DriverCardRefDto;
|
||||||
|
import at.procon.eventhub.dto.DriverRefDto;
|
||||||
|
import at.procon.eventhub.dto.EventHubEventDto;
|
||||||
|
import at.procon.eventhub.dto.VehicleRefDto;
|
||||||
|
import at.procon.eventhub.dto.VehicleRegistrationRefDto;
|
||||||
|
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class TachographRuntimeIdentityResolver {
|
||||||
|
|
||||||
|
private TachographRuntimeIdentityResolver() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String driverKey(EventHubEventDto event) {
|
||||||
|
JsonNode raw = rawPayload(event);
|
||||||
|
String rawDriverKey = firstNonBlank(text(raw, "driverKey"), text(raw, "driverCardKey"));
|
||||||
|
if (rawDriverKey != null) {
|
||||||
|
return rawDriverKey;
|
||||||
|
}
|
||||||
|
DriverRefDto driverRef = event == null ? null : event.driverRef();
|
||||||
|
DriverCardRefDto driverCard = driverRef == null ? null : driverRef.driverCard();
|
||||||
|
return driverCard != null && driverCard.hasValue() ? normalize(driverCard.stableKey()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String registrationKey(EventHubEventDto event) {
|
||||||
|
JsonNode raw = rawPayload(event);
|
||||||
|
String rawRegistrationKey = canonicalRegistrationKey(text(raw, "registrationKey"));
|
||||||
|
if (rawRegistrationKey != null) {
|
||||||
|
return rawRegistrationKey;
|
||||||
|
}
|
||||||
|
VehicleRefDto vehicleRef = event == null ? null : event.vehicleRef();
|
||||||
|
VehicleRegistrationRefDto registration = vehicleRef == null ? null : vehicleRef.vehicleRegistration();
|
||||||
|
return registration != null && registration.hasValue() ? normalize(registration.stableKey()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String vehicleKey(EventHubEventDto event) {
|
||||||
|
JsonNode raw = rawPayload(event);
|
||||||
|
String rawVehicleVin = canonicalVehicleKey(text(raw, "vehicleVin"));
|
||||||
|
if (rawVehicleVin != null) {
|
||||||
|
return rawVehicleVin;
|
||||||
|
}
|
||||||
|
String rawVehicleKey = canonicalVehicleKey(text(raw, "vehicleKey"));
|
||||||
|
if (rawVehicleKey != null) {
|
||||||
|
return rawVehicleKey;
|
||||||
|
}
|
||||||
|
VehicleRefDto vehicleRef = event == null ? null : event.vehicleRef();
|
||||||
|
return vehicleRef == null ? null : canonicalVehicleKey(vehicleRef.vin());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String requestDriverKey(
|
||||||
|
UnifiedRuntimeProcessingRequest request,
|
||||||
|
List<EventHubEventDto> events
|
||||||
|
) {
|
||||||
|
if (request == null) {
|
||||||
|
return firstEventDriverKey(events);
|
||||||
|
}
|
||||||
|
if (request.driverKey() != null) {
|
||||||
|
return request.driverKey();
|
||||||
|
}
|
||||||
|
if (request.driverCardNation() != null && request.driverCardNumber() != null) {
|
||||||
|
return request.driverCardNation() + ":" + request.driverCardNumber();
|
||||||
|
}
|
||||||
|
String eventDriverKey = firstEventDriverKey(events);
|
||||||
|
if (eventDriverKey != null) {
|
||||||
|
return eventDriverKey;
|
||||||
|
}
|
||||||
|
return request.driverCardNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonNode rawPayload(EventHubEventDto event) {
|
||||||
|
if (event == null || event.payload() == null || event.payload().isNull() || event.payload().isMissingNode()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonNode raw = event.payload().get("raw");
|
||||||
|
return raw == null || raw.isNull() ? event.payload() : raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String text(JsonNode node, String field) {
|
||||||
|
if (node == null || field == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonNode value = node.get(field);
|
||||||
|
if (value == null || value.isNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String text = value.asText(null);
|
||||||
|
return text == null || text.isBlank() ? null : text.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String firstEventDriverKey(List<EventHubEventDto> events) {
|
||||||
|
for (EventHubEventDto event : events == null ? List.<EventHubEventDto>of() : events) {
|
||||||
|
String driverKey = driverKey(event);
|
||||||
|
if (driverKey != null) {
|
||||||
|
return driverKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String canonicalVehicleKey(String value) {
|
||||||
|
String normalized = normalize(value);
|
||||||
|
if (normalized == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (normalized.startsWith("VIN:")) {
|
||||||
|
return normalize(normalized.substring("VIN:".length()));
|
||||||
|
}
|
||||||
|
if (normalized.startsWith("SOURCE_VEHICLE:")
|
||||||
|
|| normalized.startsWith("REG:")
|
||||||
|
|| normalized.startsWith("VR:")
|
||||||
|
|| normalized.contains("|")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return normalized.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String canonicalRegistrationKey(String value) {
|
||||||
|
String normalized = normalize(value);
|
||||||
|
if (normalized == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return normalized.startsWith("VR:") ? normalize(normalized.substring("VR:".length())) : normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String firstNonBlank(String... values) {
|
||||||
|
if (values == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (String value : values) {
|
||||||
|
String normalized = normalize(value);
|
||||||
|
if (normalized != null) {
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String normalize(String value) {
|
||||||
|
return value == null || value.isBlank() ? null : value.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -77,7 +77,7 @@ final class TachographRawPayloadSupport {
|
||||||
if (vehicleRef == null || !vehicleRef.hasAnyReference()) {
|
if (vehicleRef == null || !vehicleRef.hasAnyReference()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
put(raw, "vehicleKey", vehicleRef.stableKey());
|
put(raw, "vehicleKey", vehicleRef.vin());
|
||||||
put(raw, "vehicleSourceEntityId", vehicleRef.sourceVehicleEntityId());
|
put(raw, "vehicleSourceEntityId", vehicleRef.sourceVehicleEntityId());
|
||||||
put(raw, "vehicleVin", vehicleRef.vin());
|
put(raw, "vehicleVin", vehicleRef.vin());
|
||||||
put(raw, "vehicleRegistrationSourceEntityId", vehicleRef.sourceRegistrationEntityId());
|
put(raw, "vehicleRegistrationSourceEntityId", vehicleRef.sourceRegistrationEntityId());
|
||||||
|
|
|
||||||
|
|
@ -257,9 +257,11 @@ public class DriverCardXmlExtractionService {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
parsedChanges.sort(Comparator.comparing(ActivityChange::from));
|
parsedChanges.sort(Comparator.comparing(ActivityChange::from));
|
||||||
for (int i = 0; i + 1 < parsedChanges.size(); i++) {
|
for (int i = 0; i < parsedChanges.size(); i++) {
|
||||||
ActivityChange current = parsedChanges.get(i);
|
ActivityChange current = parsedChanges.get(i);
|
||||||
OffsetDateTime to = parsedChanges.get(i + 1).from();
|
OffsetDateTime to = i + 1 < parsedChanges.size()
|
||||||
|
? parsedChanges.get(i + 1).from()
|
||||||
|
: OffsetDateTime.of(date.plusDays(1), LocalTime.MIDNIGHT, ZoneOffset.UTC);
|
||||||
if (!current.from().isBefore(to)) {
|
if (!current.from().isBefore(to)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,9 +282,11 @@ public class VehicleUnitXmlExtractionService {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
parsedChanges.sort(Comparator.comparing(ActivityChange::from));
|
parsedChanges.sort(Comparator.comparing(ActivityChange::from));
|
||||||
for (int i = 0; i + 1 < parsedChanges.size(); i++) {
|
for (int i = 0; i < parsedChanges.size(); i++) {
|
||||||
ActivityChange current = parsedChanges.get(i);
|
ActivityChange current = parsedChanges.get(i);
|
||||||
OffsetDateTime to = parsedChanges.get(i + 1).from();
|
OffsetDateTime to = i + 1 < parsedChanges.size()
|
||||||
|
? parsedChanges.get(i + 1).from()
|
||||||
|
: OffsetDateTime.of(date.plusDays(1), LocalTime.MIDNIGHT, ZoneOffset.UTC);
|
||||||
if (!current.from().isBefore(to)) {
|
if (!current.from().isBefore(to)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class RuntimeEventProcessingServiceTest {
|
||||||
null,
|
null,
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
"12:DRIVER-1",
|
"12:DRIVER-1",
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
package at.procon.eventhub.processing.eventprocessing.module.epl;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import at.procon.eventhub.dto.DriverCardRefDto;
|
||||||
|
import at.procon.eventhub.dto.DriverRefDto;
|
||||||
|
import at.procon.eventhub.dto.EventDomain;
|
||||||
|
import at.procon.eventhub.dto.EventHubEventDto;
|
||||||
|
import at.procon.eventhub.dto.EventLifecycle;
|
||||||
|
import at.procon.eventhub.dto.EventType;
|
||||||
|
import at.procon.eventhub.dto.VehicleRefDto;
|
||||||
|
import at.procon.eventhub.dto.VehicleRegistrationRefDto;
|
||||||
|
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class DriverWorkingTimeEplEventMapperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void usesCanonicalTachographKeysInsteadOfSourceSpecificRawVehicleIdentifiers() {
|
||||||
|
EventHubEventDto activityEvent = event(
|
||||||
|
EventDomain.DRIVER_ACTIVITY,
|
||||||
|
EventType.DRIVE,
|
||||||
|
EventLifecycle.START,
|
||||||
|
"ACT-1",
|
||||||
|
"2026-05-01T08:00:00Z"
|
||||||
|
);
|
||||||
|
EventHubEventDto cardEvent = event(
|
||||||
|
EventDomain.DRIVER_CARD,
|
||||||
|
EventType.CARD_INSERTED,
|
||||||
|
EventLifecycle.INSERT,
|
||||||
|
"CVU-1",
|
||||||
|
"2026-05-01T08:00:00Z"
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, Object> activityPoint = DriverWorkingTimeEplEventMapper.activityPointEvents(List.of(activityEvent)).getFirst();
|
||||||
|
Map<String, Object> vehicleUsagePoint = DriverWorkingTimeEplEventMapper.vehicleUsagePointEvents(List.of(cardEvent)).getFirst();
|
||||||
|
|
||||||
|
assertThat(activityPoint.get("driverKey")).isEqualTo("1:12345678901234");
|
||||||
|
assertThat(activityPoint.get("registrationKey")).isEqualTo("1:LL-158TE");
|
||||||
|
assertThat(activityPoint.get("vehicleKey")).isEqualTo("VIN123456789");
|
||||||
|
|
||||||
|
assertThat(vehicleUsagePoint.get("driverKey")).isEqualTo("1:12345678901234");
|
||||||
|
assertThat(vehicleUsagePoint.get("registrationKey")).isEqualTo("1:LL-158TE");
|
||||||
|
assertThat(vehicleUsagePoint.get("vehicleKey")).isEqualTo("VIN123456789");
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventHubEventDto event(
|
||||||
|
EventDomain domain,
|
||||||
|
EventType eventType,
|
||||||
|
EventLifecycle lifecycle,
|
||||||
|
String intervalId,
|
||||||
|
String occurredAt
|
||||||
|
) {
|
||||||
|
ObjectNode raw = JsonNodeFactory.instance.objectNode();
|
||||||
|
raw.put("intervalId", intervalId);
|
||||||
|
raw.put("sourceRowId", intervalId);
|
||||||
|
raw.put("driverKey", "1:12345678901234");
|
||||||
|
raw.put("vehicleKey", "3560|VIN123456789|9876|1:LL-158TE");
|
||||||
|
raw.put("vehicleVin", "VIN123456789");
|
||||||
|
raw.put("registrationKey", "1:LL-158TE");
|
||||||
|
raw.put("sourceKind", "DRIVER_CARD");
|
||||||
|
ObjectNode payload = JsonNodeFactory.instance.objectNode();
|
||||||
|
payload.set("raw", raw);
|
||||||
|
return new EventHubEventDto(
|
||||||
|
UUID.randomUUID(),
|
||||||
|
intervalId + ":" + lifecycle.name(),
|
||||||
|
new DriverRefDto("3560", new DriverCardRefDto("1", 1, "12345678901234")),
|
||||||
|
new VehicleRefDto(
|
||||||
|
"3560",
|
||||||
|
"VIN123456789",
|
||||||
|
"9876",
|
||||||
|
new VehicleRegistrationRefDto("1", 1, "LL-158TE")
|
||||||
|
),
|
||||||
|
OffsetDateTime.parse(occurredAt),
|
||||||
|
null,
|
||||||
|
OffsetDateTime.parse(occurredAt),
|
||||||
|
domain,
|
||||||
|
eventType,
|
||||||
|
lifecycle,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
payload,
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -58,6 +58,7 @@ class TachographDriverEsperRuntimeEventProcessingProfileTest {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
@ -103,6 +104,7 @@ class TachographDriverEsperRuntimeEventProcessingProfileTest {
|
||||||
null,
|
null,
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
"12:DRIVER-1",
|
"12:DRIVER-1",
|
||||||
Set.of("12:DRIVER-1"),
|
Set.of("12:DRIVER-1"),
|
||||||
false,
|
false,
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ class RuntimeMixedSourceEvidenceValidationServiceTest {
|
||||||
"default",
|
"default",
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
|
null,
|
||||||
"DRIVER:1",
|
"DRIVER:1",
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ class UnifiedDriverEventsRequestTest {
|
||||||
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
"default",
|
"default",
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,52 @@ class UnifiedRuntimeProcessingRequestTest {
|
||||||
assertThat(request.vehicleExpansionPaddingMinutes()).isEqualTo(30);
|
assertThat(request.vehicleExpansionPaddingMinutes()).isEqualTo(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void defaultsToBothTachographSourceKindsAndCanRestrictToOne() {
|
||||||
|
UnifiedRuntimeProcessingRequest defaultRequest = UnifiedRuntimeProcessingRequest.forDriver(
|
||||||
|
"default",
|
||||||
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
||||||
|
"DRIVER:42",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
OffsetDateTime.parse("2026-05-01T00:00:00Z"),
|
||||||
|
OffsetDateTime.parse("2026-05-02T00:00:00Z")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat(defaultRequest.tachographSourceKinds()).containsExactlyInAnyOrder(
|
||||||
|
UnifiedTachographSourceKind.DRIVER_CARD,
|
||||||
|
UnifiedTachographSourceKind.VEHICLE_UNIT
|
||||||
|
);
|
||||||
|
assertThat(defaultRequest.includesTachographSourceKind("DRIVER_CARD")).isTrue();
|
||||||
|
assertThat(defaultRequest.includesTachographSourceKind("VEHICLE_UNIT")).isTrue();
|
||||||
|
|
||||||
|
UnifiedRuntimeProcessingRequest driverCardOnlyRequest = new UnifiedRuntimeProcessingRequest(
|
||||||
|
null,
|
||||||
|
List.of(),
|
||||||
|
null,
|
||||||
|
"default",
|
||||||
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
||||||
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
|
Set.of(UnifiedTachographSourceKind.DRIVER_CARD),
|
||||||
|
null,
|
||||||
|
Set.of(),
|
||||||
|
false,
|
||||||
|
Set.of(),
|
||||||
|
false,
|
||||||
|
"DRIVER:42",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
OffsetDateTime.parse("2026-05-01T00:00:00Z"),
|
||||||
|
OffsetDateTime.parse("2026-05-02T00:00:00Z"),
|
||||||
|
true,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat(driverCardOnlyRequest.tachographSourceKinds()).containsExactly(UnifiedTachographSourceKind.DRIVER_CARD);
|
||||||
|
assertThat(driverCardOnlyRequest.includesTachographSourceKind("DRIVER_CARD")).isTrue();
|
||||||
|
assertThat(driverCardOnlyRequest.includesTachographSourceKind("VEHICLE_UNIT")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void canBuildEventHubBackedRuntimeRequest() {
|
void canBuildEventHubBackedRuntimeRequest() {
|
||||||
UnifiedRuntimeProcessingRequest request = UnifiedRuntimeProcessingRequest.forDriverFromEventHub(
|
UnifiedRuntimeProcessingRequest request = UnifiedRuntimeProcessingRequest.forDriverFromEventHub(
|
||||||
|
|
@ -138,6 +184,7 @@ class UnifiedRuntimeProcessingRequestTest {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of("12:123", "12:456"),
|
Set.of("12:123", "12:456"),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
@ -166,6 +213,7 @@ class UnifiedRuntimeProcessingRequestTest {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
true,
|
true,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
@ -194,6 +242,7 @@ class UnifiedRuntimeProcessingRequestTest {
|
||||||
null,
|
null,
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
|
null,
|
||||||
"12:123",
|
"12:123",
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -221,6 +270,7 @@ class UnifiedRuntimeProcessingRequestTest {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ class UnifiedVehicleEventsRequestTest {
|
||||||
assertThatThrownBy(() -> new UnifiedVehicleEventsRequest(
|
assertThatThrownBy(() -> new UnifiedVehicleEventsRequest(
|
||||||
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
"default",
|
"default",
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,53 @@ class RuntimeDriverVehicleEvidenceAttachmentServiceTest {
|
||||||
assertThat(result.toPartitionDebug().vehicleEvidenceDecisions()).hasSameSizeAs(result.vehicleEvidenceDecisions());
|
assertThat(result.toPartitionDebug().vehicleEvidenceDecisions()).hasSameSizeAs(result.vehicleEvidenceDecisions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void attachesEvidenceUsingCanonicalVinWhenDbRawVehicleKeyIsSourceSpecific() {
|
||||||
|
List<EventHubEventDto> driverEvents = List.of(
|
||||||
|
cardEventWithRawVehicleKey(
|
||||||
|
"card-1-in",
|
||||||
|
EventType.CARD_INSERTED,
|
||||||
|
"1:12345678901234",
|
||||||
|
"interval-1",
|
||||||
|
"SOURCE-VEH-1|VIN-1|SOURCE-REG-1|AT:W-1",
|
||||||
|
"VIN-1",
|
||||||
|
"AT:W-1",
|
||||||
|
"2026-05-01T08:00:00Z"
|
||||||
|
),
|
||||||
|
cardEventWithRawVehicleKey(
|
||||||
|
"card-1-out",
|
||||||
|
EventType.CARD_WITHDRAWN,
|
||||||
|
"1:12345678901234",
|
||||||
|
"interval-1",
|
||||||
|
"SOURCE-VEH-1|VIN-1|SOURCE-REG-1|AT:W-1",
|
||||||
|
"VIN-1",
|
||||||
|
"AT:W-1",
|
||||||
|
"2026-05-01T18:00:00Z"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
EventHubEventDto vehicleEvidence = vehicleOnlyEventWithRawVehicleKey(
|
||||||
|
"pos-inside",
|
||||||
|
"VIN-1",
|
||||||
|
"VIN-1",
|
||||||
|
null,
|
||||||
|
"2026-05-01T12:00:00Z"
|
||||||
|
);
|
||||||
|
|
||||||
|
RuntimeDriverVehicleEvidenceAttachmentResult result = service.attachVehicleEvidence(
|
||||||
|
"1:12345678901234",
|
||||||
|
driverEvents,
|
||||||
|
List.of(driverEvents.get(0), driverEvents.get(1), vehicleEvidence),
|
||||||
|
true,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat(result.vehicleUsageIntervalCount()).isEqualTo(1);
|
||||||
|
assertThat(result.attachedVehicleEvidenceEvents()).extracting(EventHubEventDto::externalSourceEventId)
|
||||||
|
.containsExactly("pos-inside");
|
||||||
|
assertThat(result.mergedEvents()).extracting(EventHubEventDto::externalSourceEventId)
|
||||||
|
.containsExactly("card-1-in", "pos-inside", "card-1-out");
|
||||||
|
}
|
||||||
|
|
||||||
private EventHubEventDto cardEvent(
|
private EventHubEventDto cardEvent(
|
||||||
String externalId,
|
String externalId,
|
||||||
EventType eventType,
|
EventType eventType,
|
||||||
|
|
@ -179,6 +226,38 @@ class RuntimeDriverVehicleEvidenceAttachmentServiceTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EventHubEventDto cardEventWithRawVehicleKey(
|
||||||
|
String externalId,
|
||||||
|
EventType eventType,
|
||||||
|
String driverKey,
|
||||||
|
String intervalId,
|
||||||
|
String rawVehicleKey,
|
||||||
|
String vin,
|
||||||
|
String registrationKey,
|
||||||
|
String occurredAt
|
||||||
|
) {
|
||||||
|
EventLifecycle lifecycle = eventType == EventType.CARD_INSERTED ? EventLifecycle.INSERT : EventLifecycle.WITHDRAW;
|
||||||
|
return new EventHubEventDto(
|
||||||
|
UUID.randomUUID(),
|
||||||
|
externalId,
|
||||||
|
new DriverRefDto(driverKey, null),
|
||||||
|
vehicleRef(vin, registrationKey),
|
||||||
|
OffsetDateTime.parse(occurredAt),
|
||||||
|
null,
|
||||||
|
OffsetDateTime.parse(occurredAt),
|
||||||
|
EventDomain.DRIVER_CARD,
|
||||||
|
eventType,
|
||||||
|
lifecycle,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
raw(driverKey, intervalId, rawVehicleKey, vin, registrationKey),
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private EventHubEventDto vehicleOnlyEvent(
|
private EventHubEventDto vehicleOnlyEvent(
|
||||||
String externalId,
|
String externalId,
|
||||||
String vehicleKey,
|
String vehicleKey,
|
||||||
|
|
@ -206,17 +285,55 @@ class RuntimeDriverVehicleEvidenceAttachmentServiceTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EventHubEventDto vehicleOnlyEventWithRawVehicleKey(
|
||||||
|
String externalId,
|
||||||
|
String rawVehicleKey,
|
||||||
|
String vin,
|
||||||
|
String registrationKey,
|
||||||
|
String occurredAt
|
||||||
|
) {
|
||||||
|
return new EventHubEventDto(
|
||||||
|
UUID.randomUUID(),
|
||||||
|
externalId,
|
||||||
|
null,
|
||||||
|
vehicleRef(vin, registrationKey),
|
||||||
|
OffsetDateTime.parse(occurredAt),
|
||||||
|
null,
|
||||||
|
OffsetDateTime.parse(occurredAt),
|
||||||
|
EventDomain.POSITION,
|
||||||
|
EventType.POSITION_RECORDED,
|
||||||
|
EventLifecycle.SNAPSHOT,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
raw(null, null, rawVehicleKey, vin, registrationKey),
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private VehicleRefDto vehicleRef(String vehicleKey, String registrationKey) {
|
private VehicleRefDto vehicleRef(String vehicleKey, String registrationKey) {
|
||||||
String[] registrationParts = registrationKey.split(":", 2);
|
String[] registrationParts = registrationKey == null ? null : registrationKey.split(":", 2);
|
||||||
return new VehicleRefDto(
|
return new VehicleRefDto(
|
||||||
"VIN:" + vehicleKey,
|
"VIN:" + vehicleKey,
|
||||||
vehicleKey,
|
vehicleKey,
|
||||||
"VR:" + registrationKey,
|
registrationKey == null ? null : "VR:" + registrationKey,
|
||||||
new VehicleRegistrationRefDto(registrationParts[0], registrationParts[1])
|
registrationParts == null ? null : new VehicleRegistrationRefDto(registrationParts[0], registrationParts[1])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonNode raw(String driverKey, String intervalId, String vehicleKey, String registrationKey) {
|
private JsonNode raw(String driverKey, String intervalId, String vehicleKey, String registrationKey) {
|
||||||
|
return raw(driverKey, intervalId, vehicleKey, vehicleKey, registrationKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode raw(
|
||||||
|
String driverKey,
|
||||||
|
String intervalId,
|
||||||
|
String rawVehicleKey,
|
||||||
|
String vehicleVin,
|
||||||
|
String registrationKey
|
||||||
|
) {
|
||||||
ObjectNode root = OBJECT_MAPPER.createObjectNode();
|
ObjectNode root = OBJECT_MAPPER.createObjectNode();
|
||||||
ObjectNode raw = root.putObject("raw");
|
ObjectNode raw = root.putObject("raw");
|
||||||
if (driverKey != null) {
|
if (driverKey != null) {
|
||||||
|
|
@ -226,8 +343,15 @@ class RuntimeDriverVehicleEvidenceAttachmentServiceTest {
|
||||||
raw.put("intervalId", intervalId);
|
raw.put("intervalId", intervalId);
|
||||||
raw.put("sourceRowId", intervalId);
|
raw.put("sourceRowId", intervalId);
|
||||||
}
|
}
|
||||||
raw.put("vehicleKey", vehicleKey);
|
if (rawVehicleKey != null) {
|
||||||
|
raw.put("vehicleKey", rawVehicleKey);
|
||||||
|
}
|
||||||
|
if (vehicleVin != null) {
|
||||||
|
raw.put("vehicleVin", vehicleVin);
|
||||||
|
}
|
||||||
|
if (registrationKey != null) {
|
||||||
raw.put("registrationKey", registrationKey);
|
raw.put("registrationKey", registrationKey);
|
||||||
|
}
|
||||||
raw.put("sourceKind", "TEST");
|
raw.put("sourceKind", "TEST");
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package at.procon.eventhub.processing.service;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import at.procon.eventhub.dto.DriverCardRefDto;
|
||||||
import at.procon.eventhub.dto.DriverRefDto;
|
import at.procon.eventhub.dto.DriverRefDto;
|
||||||
import at.procon.eventhub.dto.EventDomain;
|
import at.procon.eventhub.dto.EventDomain;
|
||||||
import at.procon.eventhub.dto.EventHubEventDto;
|
import at.procon.eventhub.dto.EventHubEventDto;
|
||||||
|
|
@ -48,6 +49,7 @@ class UnifiedRuntimeDriverTimelineServiceTest {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
@ -68,6 +70,7 @@ class UnifiedRuntimeDriverTimelineServiceTest {
|
||||||
assertThat(timeline.activityIntervals()).hasSize(1);
|
assertThat(timeline.activityIntervals()).hasSize(1);
|
||||||
assertThat(timeline.activityIntervals().get(0).intervalId()).isEqualTo("ACT-1");
|
assertThat(timeline.activityIntervals().get(0).intervalId()).isEqualTo("ACT-1");
|
||||||
assertThat(timeline.vehicleUsageIntervals()).hasSize(1);
|
assertThat(timeline.vehicleUsageIntervals()).hasSize(1);
|
||||||
|
assertThat(timeline.vehicleUsageIntervals().get(0).driverKey()).isEqualTo("12:12345678901234");
|
||||||
assertThat(timeline.vehicleUsageIntervals().get(0).intervalId()).isEqualTo("CVU-1");
|
assertThat(timeline.vehicleUsageIntervals().get(0).intervalId()).isEqualTo("CVU-1");
|
||||||
assertThat(timeline.supportEvents()).isEmpty();
|
assertThat(timeline.supportEvents()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +112,7 @@ class UnifiedRuntimeDriverTimelineServiceTest {
|
||||||
return new EventHubEventDto(
|
return new EventHubEventDto(
|
||||||
UUID.randomUUID(),
|
UUID.randomUUID(),
|
||||||
intervalId + ":" + lifecycle.name(),
|
intervalId + ":" + lifecycle.name(),
|
||||||
new DriverRefDto("DRIVER:42", null),
|
driverRef(),
|
||||||
vehicleRef(),
|
vehicleRef(),
|
||||||
OffsetDateTime.parse(occurredAt),
|
OffsetDateTime.parse(occurredAt),
|
||||||
null,
|
null,
|
||||||
|
|
@ -144,7 +147,7 @@ class UnifiedRuntimeDriverTimelineServiceTest {
|
||||||
return new EventHubEventDto(
|
return new EventHubEventDto(
|
||||||
UUID.randomUUID(),
|
UUID.randomUUID(),
|
||||||
intervalId + ":" + eventType.name(),
|
intervalId + ":" + eventType.name(),
|
||||||
new DriverRefDto("DRIVER:42", null),
|
driverRef(),
|
||||||
vehicleRef(),
|
vehicleRef(),
|
||||||
OffsetDateTime.parse(occurredAt),
|
OffsetDateTime.parse(occurredAt),
|
||||||
null,
|
null,
|
||||||
|
|
@ -166,6 +169,10 @@ class UnifiedRuntimeDriverTimelineServiceTest {
|
||||||
return new VehicleRefDto("VEH-1", "VIN-1", "VR-1", new VehicleRegistrationRefDto("12", 12, "REG-1"));
|
return new VehicleRefDto("VEH-1", "VIN-1", "VR-1", new VehicleRegistrationRefDto("12", 12, "REG-1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DriverRefDto driverRef() {
|
||||||
|
return new DriverRefDto("DRIVER:42", new DriverCardRefDto("12", 12, "12345678901234"));
|
||||||
|
}
|
||||||
|
|
||||||
private EventHubPackageRequest packageInfo(EventDomain eventDomain) {
|
private EventHubPackageRequest packageInfo(EventDomain eventDomain) {
|
||||||
EventSourceDto source = new EventSourceDto("TACHOGRAPH", "DRIVER_CARD", "SOURCE", null, null, null);
|
EventSourceDto source = new EventSourceDto("TACHOGRAPH", "DRIVER_CARD", "SOURCE", null, null, null);
|
||||||
return new EventHubPackageRequest(
|
return new EventHubPackageRequest(
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class UnifiedRuntimeEventAssemblyServiceTest {
|
||||||
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
Set.of(UnifiedEventSourceFamily.TACHOGRAPH_DB),
|
||||||
UnifiedRuntimeEventBackend.SOURCE_DB,
|
UnifiedRuntimeEventBackend.SOURCE_DB,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
false,
|
false,
|
||||||
Set.of(),
|
Set.of(),
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,11 @@ class TachographDbRowMapperTimelineMetadataTest {
|
||||||
assertThat(raw.get("sourceKind").asText()).isEqualTo("DRIVER_CARD");
|
assertThat(raw.get("sourceKind").asText()).isEqualTo("DRIVER_CARD");
|
||||||
assertThat(raw.get("extractionCode").asText()).isEqualTo("CARD_ACTIVITY");
|
assertThat(raw.get("extractionCode").asText()).isEqualTo("CARD_ACTIVITY");
|
||||||
assertThat(raw.get("sourceRowIds").get(0).asText()).isEqualTo("CA-1");
|
assertThat(raw.get("sourceRowIds").get(0).asText()).isEqualTo("CA-1");
|
||||||
assertThat(raw.get("driverKey").asText()).contains("driver-1");
|
assertThat(raw.get("driverKey").asText()).isEqualTo(started.driverRef().stableKey());
|
||||||
assertThat(raw.get("vehicleKey").asText()).contains("VIN123");
|
assertThat(raw.get("vehicleKey").asText()).isEqualTo("VIN123");
|
||||||
assertThat(raw.get("registrationKey").asText()).contains("W-12345");
|
assertThat(raw.get("registrationKey").asText()).isEqualTo(started.vehicleRef().vehicleRegistration().stableKey());
|
||||||
|
|
||||||
var timeline = reconstructor.reconstruct(UUID.randomUUID(), "driver-1", List.of(started, ended));
|
var timeline = reconstructor.reconstruct(UUID.randomUUID(), started.driverRef().stableKey(), List.of(started, ended));
|
||||||
|
|
||||||
assertThat(timeline.activityIntervals()).hasSize(1);
|
assertThat(timeline.activityIntervals()).hasSize(1);
|
||||||
var interval = timeline.activityIntervals().getFirst();
|
var interval = timeline.activityIntervals().getFirst();
|
||||||
|
|
@ -52,8 +52,8 @@ class TachographDbRowMapperTimelineMetadataTest {
|
||||||
assertThat(interval.activityType()).isEqualTo("DRIVE");
|
assertThat(interval.activityType()).isEqualTo("DRIVE");
|
||||||
assertThat(interval.sourceKind()).isEqualTo("DRIVER_CARD");
|
assertThat(interval.sourceKind()).isEqualTo("DRIVER_CARD");
|
||||||
assertThat(interval.sourceIntervalIds()).containsExactly("CA-1");
|
assertThat(interval.sourceIntervalIds()).containsExactly("CA-1");
|
||||||
assertThat(interval.registrationKey()).contains("W-12345");
|
assertThat(interval.registrationKey()).isEqualTo(started.vehicleRef().vehicleRegistration().stableKey());
|
||||||
assertThat(interval.vehicleKey()).contains("VIN123");
|
assertThat(interval.vehicleKey()).isEqualTo("VIN123");
|
||||||
assertThat(interval.durationSeconds()).isEqualTo(4_500L);
|
assertThat(interval.durationSeconds()).isEqualTo(4_500L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,17 +67,17 @@ class TachographDbRowMapperTimelineMetadataTest {
|
||||||
JsonNode raw = inserted.payload().get("raw");
|
JsonNode raw = inserted.payload().get("raw");
|
||||||
assertThat(raw.get("intervalId").asText()).isEqualTo("TACHOGRAPH:CARD_VEHICLES_USED:CVU-1");
|
assertThat(raw.get("intervalId").asText()).isEqualTo("TACHOGRAPH:CARD_VEHICLES_USED:CVU-1");
|
||||||
assertThat(raw.get("sourceRowIds").get(0).asText()).isEqualTo("CVU-1");
|
assertThat(raw.get("sourceRowIds").get(0).asText()).isEqualTo("CVU-1");
|
||||||
assertThat(raw.get("registrationKey").asText()).contains("W-12345");
|
assertThat(raw.get("registrationKey").asText()).isEqualTo(inserted.vehicleRef().vehicleRegistration().stableKey());
|
||||||
|
|
||||||
var timeline = reconstructor.reconstruct(UUID.randomUUID(), "driver-1", List.of(inserted, withdrawn));
|
var timeline = reconstructor.reconstruct(UUID.randomUUID(), inserted.driverRef().stableKey(), List.of(inserted, withdrawn));
|
||||||
|
|
||||||
assertThat(timeline.vehicleUsageIntervals()).hasSize(1);
|
assertThat(timeline.vehicleUsageIntervals()).hasSize(1);
|
||||||
var usage = timeline.vehicleUsageIntervals().getFirst();
|
var usage = timeline.vehicleUsageIntervals().getFirst();
|
||||||
assertThat(usage.intervalId()).isEqualTo("TACHOGRAPH:CARD_VEHICLES_USED:CVU-1");
|
assertThat(usage.intervalId()).isEqualTo("TACHOGRAPH:CARD_VEHICLES_USED:CVU-1");
|
||||||
assertThat(usage.sourceKind()).isEqualTo("DRIVER_CARD");
|
assertThat(usage.sourceKind()).isEqualTo("DRIVER_CARD");
|
||||||
assertThat(usage.sourceIntervalIds()).containsExactly("CVU-1");
|
assertThat(usage.sourceIntervalIds()).containsExactly("CVU-1");
|
||||||
assertThat(usage.registrationKey()).contains("W-12345");
|
assertThat(usage.registrationKey()).isEqualTo(inserted.vehicleRef().vehicleRegistration().stableKey());
|
||||||
assertThat(usage.vehicleKey()).contains("VIN123");
|
assertThat(usage.vehicleKey()).isEqualTo("VIN123");
|
||||||
assertThat(usage.odometerBeginKm()).isEqualTo(120L);
|
assertThat(usage.odometerBeginKm()).isEqualTo(120L);
|
||||||
assertThat(usage.odometerEndKm()).isEqualTo(120L);
|
assertThat(usage.odometerEndKm()).isEqualTo(120L);
|
||||||
assertThat(usage.durationSeconds()).isEqualTo(43_200L);
|
assertThat(usage.durationSeconds()).isEqualTo(43_200L);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import at.procon.eventhub.tachographfilesession.model.DriverExtractionSession;
|
||||||
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
|
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
|
||||||
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
|
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
@ -45,10 +46,14 @@ class DriverCardXmlExtractionServiceTest {
|
||||||
assertThat(driver.vehicleRegistrations()).hasSize(2);
|
assertThat(driver.vehicleRegistrations()).hasSize(2);
|
||||||
assertThat(driver.vehicles()).hasSize(2);
|
assertThat(driver.vehicles()).hasSize(2);
|
||||||
assertThat(driver.cardVehicleUsageIntervals()).hasSize(2);
|
assertThat(driver.cardVehicleUsageIntervals()).hasSize(2);
|
||||||
assertThat(driver.cardActivityIntervals()).hasSize(3);
|
assertThat(driver.cardActivityIntervals()).hasSize(5);
|
||||||
assertThat(driver.cardActivityIntervals().get(0).registrationKey()).isEqualTo("12:W-12345A");
|
assertThat(driver.cardActivityIntervals().get(0).registrationKey()).isEqualTo("12:W-12345A");
|
||||||
assertThat(driver.cardActivityIntervals().get(1).to()).isEqualTo(driver.cardVehicleUsageIntervals().get(0).to().plusSeconds(1));
|
assertThat(driver.cardActivityIntervals().get(1).to()).isEqualTo(driver.cardVehicleUsageIntervals().get(0).to().plusSeconds(1));
|
||||||
assertThat(driver.cardActivityIntervals().get(2).registrationKey()).isEqualTo("12:W-54321B");
|
assertThat(driver.cardActivityIntervals().get(2).registrationKey()).isEqualTo("12:W-54321B");
|
||||||
|
assertThat(driver.cardActivityIntervals().get(3).activityType()).isEqualTo("BREAK_REST");
|
||||||
|
assertThat(driver.cardActivityIntervals().get(3).to()).isEqualTo(OffsetDateTime.parse("2026-04-01T18:00:01Z"));
|
||||||
|
assertThat(driver.cardActivityIntervals().get(4).to()).isEqualTo(OffsetDateTime.parse("2026-04-02T00:00:00Z"));
|
||||||
|
assertThat(driver.cardActivityIntervals().get(4).registrationKey()).isNull();
|
||||||
assertThat(driver.supportEvents()).hasSize(5);
|
assertThat(driver.supportEvents()).hasSize(5);
|
||||||
assertThat(driver.supportEvents()).extracting("eventDomain")
|
assertThat(driver.supportEvents()).extracting("eventDomain")
|
||||||
.containsExactly("PLACE", "POSITION", "SPECIFIC_CONDITION", "BORDER_CROSSING", "LOAD_UNLOAD");
|
.containsExactly("PLACE", "POSITION", "SPECIFIC_CONDITION", "BORDER_CROSSING", "LOAD_UNLOAD");
|
||||||
|
|
@ -79,10 +84,10 @@ class DriverCardXmlExtractionServiceTest {
|
||||||
);
|
);
|
||||||
|
|
||||||
DriverExtractionSession driver = session.driversByKey().values().iterator().next();
|
DriverExtractionSession driver = session.driversByKey().values().iterator().next();
|
||||||
assertThat(driver.cardActivityIntervals()).hasSize(3);
|
assertThat(driver.cardActivityIntervals()).hasSize(5);
|
||||||
assertThat(driver.cardActivityIntervals())
|
assertThat(driver.cardActivityIntervals())
|
||||||
.extracting(interval -> interval.from().toString())
|
.extracting(interval -> interval.from().toString())
|
||||||
.contains("2026-04-01T08:00Z", "2026-04-01T12:00Z");
|
.contains("2026-04-01T08:00Z", "2026-04-01T12:00Z", "2026-04-01T18:00:01Z");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -108,8 +113,11 @@ class DriverCardXmlExtractionServiceTest {
|
||||||
DriverExtractionSession driver = session.driversByKey().values().iterator().next();
|
DriverExtractionSession driver = session.driversByKey().values().iterator().next();
|
||||||
assertThat(driver.cardVehicleUsageIntervals()).hasSize(2);
|
assertThat(driver.cardVehicleUsageIntervals()).hasSize(2);
|
||||||
assertThat(driver.cardVehicleUsageIntervals().get(1).to()).isNull();
|
assertThat(driver.cardVehicleUsageIntervals().get(1).to()).isNull();
|
||||||
assertThat(driver.cardActivityIntervals()).hasSize(3);
|
assertThat(driver.cardActivityIntervals()).hasSize(4);
|
||||||
assertThat(driver.cardActivityIntervals().get(2).registrationKey()).isEqualTo("12:W-54321B");
|
assertThat(driver.cardActivityIntervals().get(2).registrationKey()).isEqualTo("12:W-54321B");
|
||||||
|
assertThat(driver.cardActivityIntervals().get(3).activityType()).isEqualTo("BREAK_REST");
|
||||||
|
assertThat(driver.cardActivityIntervals().get(3).to()).isEqualTo(OffsetDateTime.parse("2026-04-02T00:00:00Z"));
|
||||||
|
assertThat(driver.cardActivityIntervals().get(3).registrationKey()).isEqualTo("12:W-54321B");
|
||||||
assertThat(driver.supportEvents()).hasSize(5);
|
assertThat(driver.supportEvents()).hasSize(5);
|
||||||
assertThat(driver.supportEvents().stream()
|
assertThat(driver.supportEvents().stream()
|
||||||
.filter(event -> "12:W-54321B".equals(event.registrationKey()))
|
.filter(event -> "12:W-54321B".equals(event.registrationKey()))
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
|
||||||
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
|
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
@ -52,9 +53,11 @@ class VehicleUnitXmlExtractionServiceTest {
|
||||||
assertThat(firstDriver.cardVehicleUsageIntervals()).hasSize(1);
|
assertThat(firstDriver.cardVehicleUsageIntervals()).hasSize(1);
|
||||||
assertThat(firstDriver.cardVehicleUsageIntervals().get(0).from().toString()).isEqualTo("2026-04-01T08:00Z");
|
assertThat(firstDriver.cardVehicleUsageIntervals().get(0).from().toString()).isEqualTo("2026-04-01T08:00Z");
|
||||||
assertThat(firstDriver.cardVehicleUsageIntervals().get(0).to().toString()).isEqualTo("2026-04-01T11:00Z");
|
assertThat(firstDriver.cardVehicleUsageIntervals().get(0).to().toString()).isEqualTo("2026-04-01T11:00Z");
|
||||||
assertThat(firstDriver.cardActivityIntervals()).hasSize(2);
|
assertThat(firstDriver.cardActivityIntervals()).hasSize(3);
|
||||||
assertThat(firstDriver.cardActivityIntervals().get(0).activityType()).isEqualTo("WORK");
|
assertThat(firstDriver.cardActivityIntervals().get(0).activityType()).isEqualTo("WORK");
|
||||||
assertThat(firstDriver.cardActivityIntervals().get(1).activityType()).isEqualTo("DRIVE");
|
assertThat(firstDriver.cardActivityIntervals().get(1).activityType()).isEqualTo("DRIVE");
|
||||||
|
assertThat(firstDriver.cardActivityIntervals().get(2).activityType()).isEqualTo("BREAK_REST");
|
||||||
|
assertThat(firstDriver.cardActivityIntervals().get(2).to()).isEqualTo(OffsetDateTime.parse("2026-04-01T11:00:01Z"));
|
||||||
assertThat(firstDriver.supportEvents()).hasSize(1);
|
assertThat(firstDriver.supportEvents()).hasSize(1);
|
||||||
assertThat(firstDriver.supportEvents().get(0).eventDomain()).isEqualTo("PLACE");
|
assertThat(firstDriver.supportEvents().get(0).eventDomain()).isEqualTo("PLACE");
|
||||||
assertThat(firstDriver.supportEvents().get(0).eventType()).isEqualTo("BEGIN_DAILY_WORK_PERIOD");
|
assertThat(firstDriver.supportEvents().get(0).eventType()).isEqualTo("BEGIN_DAILY_WORK_PERIOD");
|
||||||
|
|
@ -63,8 +66,10 @@ class VehicleUnitXmlExtractionServiceTest {
|
||||||
|
|
||||||
assertThat(secondDriver.cardVehicleUsageIntervals()).hasSize(1);
|
assertThat(secondDriver.cardVehicleUsageIntervals()).hasSize(1);
|
||||||
assertThat(secondDriver.cardVehicleUsageIntervals().get(0).to()).isNull();
|
assertThat(secondDriver.cardVehicleUsageIntervals().get(0).to()).isNull();
|
||||||
assertThat(secondDriver.cardActivityIntervals()).hasSize(1);
|
assertThat(secondDriver.cardActivityIntervals()).hasSize(2);
|
||||||
assertThat(secondDriver.cardActivityIntervals().get(0).from().toString()).isEqualTo("2026-04-02T07:30Z");
|
assertThat(secondDriver.cardActivityIntervals().get(0).from().toString()).isEqualTo("2026-04-02T07:30Z");
|
||||||
|
assertThat(secondDriver.cardActivityIntervals().get(1).activityType()).isEqualTo("DRIVE");
|
||||||
|
assertThat(secondDriver.cardActivityIntervals().get(1).to()).isEqualTo(OffsetDateTime.parse("2026-04-03T00:00:00Z"));
|
||||||
assertThat(secondDriver.supportEvents()).hasSize(6);
|
assertThat(secondDriver.supportEvents()).hasSize(6);
|
||||||
assertThat(secondDriver.supportEvents()).extracting("eventDomain")
|
assertThat(secondDriver.supportEvents()).extracting("eventDomain")
|
||||||
.containsExactly("POSITION", "SPECIFIC_CONDITION", "BORDER_CROSSING", "LOAD_UNLOAD", "SPEEDING", "SPEEDING");
|
.containsExactly("POSITION", "SPECIFIC_CONDITION", "BORDER_CROSSING", "LOAD_UNLOAD", "SPEEDING", "SPEEDING");
|
||||||
|
|
@ -77,7 +82,7 @@ class VehicleUnitXmlExtractionServiceTest {
|
||||||
assertThat(secondDriver.supportEvents().get(4).eventLifecycle()).isEqualTo("BEGIN");
|
assertThat(secondDriver.supportEvents().get(4).eventLifecycle()).isEqualTo("BEGIN");
|
||||||
assertThat(secondDriver.supportEvents().get(5).eventLifecycle()).isEqualTo("END");
|
assertThat(secondDriver.supportEvents().get(5).eventLifecycle()).isEqualTo("END");
|
||||||
|
|
||||||
assertThat(session.warnings()).isEmpty();
|
assertThat(session.warnings()).extracting("code").containsExactly("VU_ACTIVITY_UNASSIGNED");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue