Add unified vehicle event sources
This commit is contained in:
parent
04d7bf513e
commit
8f5e51a5c1
|
|
@ -18,6 +18,7 @@ import at.procon.eventhub.dto.SourcePackageRefDto;
|
|||
import at.procon.eventhub.dto.VehicleRefDto;
|
||||
import at.procon.eventhub.dto.VehicleRegistrationRefDto;
|
||||
import at.procon.eventhub.processing.model.UnifiedDriverEventsRequest;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
|
@ -48,6 +49,57 @@ public class EventHubEventReadRepository {
|
|||
UnifiedDriverEventsRequest request,
|
||||
String providerKey,
|
||||
List<String> sourceKinds
|
||||
) {
|
||||
return findEvents(
|
||||
request.tenantKey(),
|
||||
request.occurredFrom(),
|
||||
request.occurredTo(),
|
||||
request.driverSourceEntityId(),
|
||||
request.driverCardNation(),
|
||||
request.driverCardNumber(),
|
||||
request.vehicleSourceEntityId(),
|
||||
request.vin(),
|
||||
request.registrationNation(),
|
||||
request.registrationNumber(),
|
||||
providerKey,
|
||||
sourceKinds
|
||||
);
|
||||
}
|
||||
|
||||
public List<EventHubEventDto> findEventsByVehicle(
|
||||
UnifiedVehicleEventsRequest request,
|
||||
String providerKey,
|
||||
List<String> sourceKinds
|
||||
) {
|
||||
return findEvents(
|
||||
request.tenantKey(),
|
||||
request.occurredFrom(),
|
||||
request.occurredTo(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
request.vehicleSourceEntityId(),
|
||||
request.vin(),
|
||||
request.registrationNation(),
|
||||
request.registrationNumber(),
|
||||
providerKey,
|
||||
sourceKinds
|
||||
);
|
||||
}
|
||||
|
||||
private List<EventHubEventDto> findEvents(
|
||||
String tenantKey,
|
||||
OffsetDateTime occurredFrom,
|
||||
OffsetDateTime occurredTo,
|
||||
String driverSourceEntityId,
|
||||
String driverCardNation,
|
||||
String driverCardNumber,
|
||||
String vehicleSourceEntityId,
|
||||
String vin,
|
||||
String registrationNation,
|
||||
String registrationNumber,
|
||||
String providerKey,
|
||||
List<String> sourceKinds
|
||||
) {
|
||||
StringBuilder sql = new StringBuilder(
|
||||
"""
|
||||
|
|
@ -127,7 +179,7 @@ public class EventHubEventReadRepository {
|
|||
);
|
||||
|
||||
List<Object> params = new ArrayList<>();
|
||||
params.add(request.tenantKey());
|
||||
params.add(tenantKey);
|
||||
params.add(providerKey);
|
||||
|
||||
if (sourceKinds != null && !sourceKinds.isEmpty()) {
|
||||
|
|
@ -141,40 +193,40 @@ public class EventHubEventReadRepository {
|
|||
}
|
||||
sql.append(")");
|
||||
}
|
||||
if (request.occurredFrom() != null) {
|
||||
if (occurredFrom != null) {
|
||||
sql.append(" and event.occurred_at >= ?");
|
||||
params.add(request.occurredFrom());
|
||||
params.add(occurredFrom);
|
||||
}
|
||||
if (request.occurredTo() != null) {
|
||||
if (occurredTo != null) {
|
||||
sql.append(" and event.occurred_at <= ?");
|
||||
params.add(request.occurredTo());
|
||||
params.add(occurredTo);
|
||||
}
|
||||
if (request.driverSourceEntityId() != null) {
|
||||
if (driverSourceEntityId != null) {
|
||||
sql.append(" and driver.source_driver_entity_id = ?");
|
||||
params.add(request.driverSourceEntityId());
|
||||
params.add(driverSourceEntityId);
|
||||
}
|
||||
if (request.driverCardNumber() != null) {
|
||||
if (driverCardNumber != null) {
|
||||
sql.append(" and driver_card.card_number = ?");
|
||||
params.add(request.driverCardNumber());
|
||||
if (request.driverCardNation() != null) {
|
||||
params.add(driverCardNumber);
|
||||
if (driverCardNation != null) {
|
||||
sql.append(" and driver_card.nation = ?");
|
||||
params.add(request.driverCardNation());
|
||||
params.add(driverCardNation);
|
||||
}
|
||||
}
|
||||
if (request.vehicleSourceEntityId() != null) {
|
||||
if (vehicleSourceEntityId != null) {
|
||||
sql.append(" and vehicle.source_vehicle_entity_id = ?");
|
||||
params.add(request.vehicleSourceEntityId());
|
||||
params.add(vehicleSourceEntityId);
|
||||
}
|
||||
if (request.vin() != null) {
|
||||
if (vin != null) {
|
||||
sql.append(" and vehicle.vin = ?");
|
||||
params.add(request.vin());
|
||||
params.add(vin);
|
||||
}
|
||||
if (request.registrationNumber() != null) {
|
||||
if (registrationNumber != null) {
|
||||
sql.append(" and registration.registration_number = ?");
|
||||
params.add(request.registrationNumber());
|
||||
if (request.registrationNation() != null) {
|
||||
params.add(registrationNumber);
|
||||
if (registrationNation != null) {
|
||||
sql.append(" and registration.nation = ?");
|
||||
params.add(request.registrationNation());
|
||||
params.add(registrationNation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
package at.procon.eventhub.processing.model;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public record UnifiedVehicleEventsRequest(
|
||||
UnifiedEventSourceFamily sourceFamily,
|
||||
UUID sessionId,
|
||||
String tenantKey,
|
||||
String vehicleSourceEntityId,
|
||||
String vin,
|
||||
String registrationNation,
|
||||
String registrationNumber,
|
||||
OffsetDateTime occurredFrom,
|
||||
OffsetDateTime occurredTo
|
||||
) {
|
||||
public UnifiedVehicleEventsRequest {
|
||||
Objects.requireNonNull(sourceFamily, "sourceFamily must not be null");
|
||||
tenantKey = normalize(tenantKey);
|
||||
vehicleSourceEntityId = normalize(vehicleSourceEntityId);
|
||||
vin = normalizeUpper(vin);
|
||||
registrationNation = normalizeUpper(registrationNation);
|
||||
registrationNumber = normalize(registrationNumber);
|
||||
if (occurredFrom != null && occurredTo != null && occurredTo.isBefore(occurredFrom)) {
|
||||
throw new IllegalArgumentException("occurredTo must not be before occurredFrom");
|
||||
}
|
||||
if (sourceFamily == UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION) {
|
||||
Objects.requireNonNull(sessionId, "sessionId must not be null");
|
||||
} else if (tenantKey == null) {
|
||||
throw new IllegalArgumentException("tenantKey must not be blank");
|
||||
}
|
||||
if (!hasVehicleSelector(vehicleSourceEntityId, vin, registrationNumber)) {
|
||||
throw new IllegalArgumentException("At least one vehicle selector must be provided.");
|
||||
}
|
||||
}
|
||||
|
||||
public static UnifiedVehicleEventsRequest forTachographFileSession(
|
||||
UUID sessionId,
|
||||
String vehicleSourceEntityId,
|
||||
String vin,
|
||||
String registrationNation,
|
||||
String registrationNumber,
|
||||
OffsetDateTime occurredFrom,
|
||||
OffsetDateTime occurredTo
|
||||
) {
|
||||
return new UnifiedVehicleEventsRequest(
|
||||
UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION,
|
||||
sessionId,
|
||||
null,
|
||||
vehicleSourceEntityId,
|
||||
vin,
|
||||
registrationNation,
|
||||
registrationNumber,
|
||||
occurredFrom,
|
||||
occurredTo
|
||||
);
|
||||
}
|
||||
|
||||
public static UnifiedVehicleEventsRequest forTachographDb(
|
||||
String tenantKey,
|
||||
String vehicleSourceEntityId,
|
||||
String vin,
|
||||
String registrationNation,
|
||||
String registrationNumber,
|
||||
OffsetDateTime occurredFrom,
|
||||
OffsetDateTime occurredTo
|
||||
) {
|
||||
return new UnifiedVehicleEventsRequest(
|
||||
UnifiedEventSourceFamily.TACHOGRAPH_DB,
|
||||
null,
|
||||
tenantKey,
|
||||
vehicleSourceEntityId,
|
||||
vin,
|
||||
registrationNation,
|
||||
registrationNumber,
|
||||
occurredFrom,
|
||||
occurredTo
|
||||
);
|
||||
}
|
||||
|
||||
public static UnifiedVehicleEventsRequest forYellowFoxDb(
|
||||
String tenantKey,
|
||||
String vehicleSourceEntityId,
|
||||
String vin,
|
||||
String registrationNation,
|
||||
String registrationNumber,
|
||||
OffsetDateTime occurredFrom,
|
||||
OffsetDateTime occurredTo
|
||||
) {
|
||||
return new UnifiedVehicleEventsRequest(
|
||||
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
||||
null,
|
||||
tenantKey,
|
||||
vehicleSourceEntityId,
|
||||
vin,
|
||||
registrationNation,
|
||||
registrationNumber,
|
||||
occurredFrom,
|
||||
occurredTo
|
||||
);
|
||||
}
|
||||
|
||||
public boolean hasVehicleSelector() {
|
||||
return hasVehicleSelector(vehicleSourceEntityId, vin, registrationNumber);
|
||||
}
|
||||
|
||||
private static boolean hasVehicleSelector(String vehicleSourceEntityId, String vin, String registrationNumber) {
|
||||
return vehicleSourceEntityId != null || vin != null || registrationNumber != null;
|
||||
}
|
||||
|
||||
private static String normalize(String value) {
|
||||
return value == null || value.isBlank() ? null : value.trim();
|
||||
}
|
||||
|
||||
private static String normalizeUpper(String value) {
|
||||
return value == null || value.isBlank() ? null : value.trim().toUpperCase();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package at.procon.eventhub.processing.service;
|
||||
|
||||
import at.procon.eventhub.dto.EventHubEventDto;
|
||||
import at.procon.eventhub.persistence.EventHubEventReadRepository;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TachographDbUnifiedVehicleEventSource implements UnifiedVehicleEventSource {
|
||||
|
||||
private static final List<String> SOURCE_KINDS = List.of("DRIVER_CARD", "VEHICLE_UNIT");
|
||||
|
||||
private final EventHubEventReadRepository repository;
|
||||
|
||||
public TachographDbUnifiedVehicleEventSource(EventHubEventReadRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(UnifiedVehicleEventsRequest request) {
|
||||
return request.sourceFamily() == UnifiedEventSourceFamily.TACHOGRAPH_DB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request) {
|
||||
return repository.findEventsByVehicle(request, "TACHOGRAPH", SOURCE_KINDS);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package at.procon.eventhub.processing.service;
|
||||
|
||||
import at.procon.eventhub.dto.EventHubEventDto;
|
||||
import at.procon.eventhub.dto.VehicleRefDto;
|
||||
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
|
||||
import at.procon.eventhub.tachographfilesession.service.DriverTimelineEventBuilder;
|
||||
import at.procon.eventhub.tachographfilesession.service.TachographFileSessionNotFoundException;
|
||||
import at.procon.eventhub.tachographfilesession.service.TachographFileSessionRepository;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TachographFileSessionUnifiedVehicleEventSource implements UnifiedVehicleEventSource {
|
||||
|
||||
private final TachographFileSessionRepository repository;
|
||||
private final DriverTimelineEventBuilder eventBuilder;
|
||||
|
||||
public TachographFileSessionUnifiedVehicleEventSource(
|
||||
TachographFileSessionRepository repository,
|
||||
DriverTimelineEventBuilder eventBuilder
|
||||
) {
|
||||
this.repository = repository;
|
||||
this.eventBuilder = eventBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(UnifiedVehicleEventsRequest request) {
|
||||
return request.sourceFamily() == UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request) {
|
||||
TachographFileSession session = repository.find(request.sessionId())
|
||||
.orElseThrow(() -> new TachographFileSessionNotFoundException(request.sessionId()));
|
||||
return session.driversByKey().values().stream()
|
||||
.flatMap(driver -> eventBuilder.buildEvents(session, driver).stream())
|
||||
.filter(event -> matchesVehicle(event.vehicleRef(), request))
|
||||
.filter(event -> withinWindow(event.occurredAt(), request.occurredFrom(), request.occurredTo()))
|
||||
.distinct()
|
||||
.toList();
|
||||
}
|
||||
|
||||
private boolean matchesVehicle(VehicleRefDto vehicleRef, UnifiedVehicleEventsRequest request) {
|
||||
if (vehicleRef == null || !vehicleRef.hasAnyReference()) {
|
||||
return false;
|
||||
}
|
||||
if (request.vehicleSourceEntityId() != null
|
||||
&& request.vehicleSourceEntityId().equals(vehicleRef.sourceVehicleEntityId())) {
|
||||
return true;
|
||||
}
|
||||
if (request.vin() != null && request.vin().equals(vehicleRef.vin())) {
|
||||
return true;
|
||||
}
|
||||
return request.registrationNumber() != null
|
||||
&& vehicleRef.vehicleRegistration() != null
|
||||
&& request.registrationNumber().equals(vehicleRef.vehicleRegistration().number())
|
||||
&& (request.registrationNation() == null
|
||||
|| request.registrationNation().equals(vehicleRef.vehicleRegistration().nation()));
|
||||
}
|
||||
|
||||
private boolean withinWindow(
|
||||
OffsetDateTime occurredAt,
|
||||
OffsetDateTime occurredFrom,
|
||||
OffsetDateTime occurredTo
|
||||
) {
|
||||
if (occurredAt == null) {
|
||||
return false;
|
||||
}
|
||||
if (occurredFrom != null && occurredAt.isBefore(occurredFrom)) {
|
||||
return false;
|
||||
}
|
||||
return occurredTo == null || !occurredAt.isAfter(occurredTo);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package at.procon.eventhub.processing.service;
|
||||
|
||||
import at.procon.eventhub.dto.EventHubEventDto;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import java.util.List;
|
||||
|
||||
public interface UnifiedVehicleEventSource {
|
||||
|
||||
boolean supports(UnifiedVehicleEventsRequest request);
|
||||
|
||||
List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package at.procon.eventhub.processing.service;
|
||||
|
||||
import at.procon.eventhub.dto.EventHubEventDto;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UnifiedVehicleEventSourceService {
|
||||
|
||||
private final List<UnifiedVehicleEventSource> eventSources;
|
||||
|
||||
public UnifiedVehicleEventSourceService(List<UnifiedVehicleEventSource> eventSources) {
|
||||
this.eventSources = List.copyOf(eventSources);
|
||||
}
|
||||
|
||||
public List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request) {
|
||||
return eventSources.stream()
|
||||
.filter(source -> source.supports(request))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> unsupportedSource(request.sourceFamily().name()))
|
||||
.loadVehicleEvents(request);
|
||||
}
|
||||
|
||||
private IllegalArgumentException unsupportedSource(String sourceFamily) {
|
||||
return new IllegalArgumentException("No unified vehicle event source is registered for source family " + sourceFamily + ".");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package at.procon.eventhub.processing.service;
|
||||
|
||||
import at.procon.eventhub.dto.EventHubEventDto;
|
||||
import at.procon.eventhub.persistence.EventHubEventReadRepository;
|
||||
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class YellowFoxDbUnifiedVehicleEventSource implements UnifiedVehicleEventSource {
|
||||
|
||||
private final EventHubEventReadRepository repository;
|
||||
|
||||
public YellowFoxDbUnifiedVehicleEventSource(EventHubEventReadRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(UnifiedVehicleEventsRequest request) {
|
||||
return request.sourceFamily() == UnifiedEventSourceFamily.YELLOWFOX_DB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EventHubEventDto> loadVehicleEvents(UnifiedVehicleEventsRequest request) {
|
||||
return repository.findEventsByVehicle(request, "YELLOWFOX", List.of("TELEMATICS_PLATFORM"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package at.procon.eventhub.processing.model;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class UnifiedVehicleEventsRequestTest {
|
||||
|
||||
@Test
|
||||
void buildsFileSessionVehicleRequest() {
|
||||
UUID sessionId = UUID.randomUUID();
|
||||
|
||||
UnifiedVehicleEventsRequest request = UnifiedVehicleEventsRequest.forTachographFileSession(
|
||||
sessionId,
|
||||
" VEHICLE:1 ",
|
||||
"wdb123",
|
||||
"at",
|
||||
"W-123AB",
|
||||
OffsetDateTime.parse("2026-05-01T00:00:00Z"),
|
||||
OffsetDateTime.parse("2026-05-02T00:00:00Z")
|
||||
);
|
||||
|
||||
assertThat(request.sourceFamily()).isEqualTo(UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION);
|
||||
assertThat(request.sessionId()).isEqualTo(sessionId);
|
||||
assertThat(request.vehicleSourceEntityId()).isEqualTo("VEHICLE:1");
|
||||
assertThat(request.vin()).isEqualTo("WDB123");
|
||||
assertThat(request.registrationNation()).isEqualTo("AT");
|
||||
assertThat(request.registrationNumber()).isEqualTo("W-123AB");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildsDbVehicleRequest() {
|
||||
UnifiedVehicleEventsRequest request = UnifiedVehicleEventsRequest.forTachographDb(
|
||||
" default ",
|
||||
null,
|
||||
"vin-42",
|
||||
"de",
|
||||
"B-123",
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
assertThat(request.sourceFamily()).isEqualTo(UnifiedEventSourceFamily.TACHOGRAPH_DB);
|
||||
assertThat(request.tenantKey()).isEqualTo("default");
|
||||
assertThat(request.vin()).isEqualTo("VIN-42");
|
||||
assertThat(request.registrationNation()).isEqualTo("DE");
|
||||
assertThat(request.registrationNumber()).isEqualTo("B-123");
|
||||
assertThat(request.hasVehicleSelector()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsRequestWithoutVehicleSelector() {
|
||||
assertThatThrownBy(() -> new UnifiedVehicleEventsRequest(
|
||||
UnifiedEventSourceFamily.YELLOWFOX_DB,
|
||||
null,
|
||||
"default",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("At least one vehicle selector");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
package at.procon.eventhub.processing.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import at.procon.eventhub.config.EventHubProperties;
|
||||
import at.procon.eventhub.dto.EventDomain;
|
||||
import at.procon.eventhub.dto.EventLifecycle;
|
||||
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
|
||||
import at.procon.eventhub.service.EventDetailsFactory;
|
||||
import at.procon.eventhub.tachographfilesession.model.DriverExtractionSession;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedCardActivityInterval;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedCardVehicleUsageInterval;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedDriver;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedDriverCard;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedSupportEvent;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedVehicle;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractedVehicleRegistration;
|
||||
import at.procon.eventhub.tachographfilesession.model.ExtractionStats;
|
||||
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
|
||||
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
|
||||
import at.procon.eventhub.tachographfilesession.service.DriverKeyFactory;
|
||||
import at.procon.eventhub.tachographfilesession.service.DriverTimelineBuilder;
|
||||
import at.procon.eventhub.tachographfilesession.service.InMemoryTachographFileSessionRepository;
|
||||
import at.procon.eventhub.tachographfilesession.service.IntervalBackedDriverTimelineEventBuilder;
|
||||
import at.procon.eventhub.tachographfilesession.service.TachographFileSessionRepository;
|
||||
import at.procon.eventhub.tachographfilesession.service.VehicleKeyFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class UnifiedVehicleEventSourceServiceTest {
|
||||
|
||||
@Test
|
||||
void loadsNormalizedFileSessionVehicleEventsThroughUnifiedService() {
|
||||
EventHubProperties properties = new EventHubProperties();
|
||||
TachographFileSessionRepository repository = new InMemoryTachographFileSessionRepository(properties);
|
||||
DriverTimelineBuilder timelineBuilder = new DriverTimelineBuilder();
|
||||
UnifiedVehicleEventSourceService service = new UnifiedVehicleEventSourceService(List.of(
|
||||
new TachographFileSessionUnifiedVehicleEventSource(
|
||||
repository,
|
||||
new IntervalBackedDriverTimelineEventBuilder(
|
||||
timelineBuilder,
|
||||
new DriverKeyFactory(),
|
||||
new VehicleKeyFactory(),
|
||||
new EventDetailsFactory(new ObjectMapper())
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
DriverExtractionSession driver = driver();
|
||||
TachographFileSession session = session(driver);
|
||||
repository.save(session);
|
||||
|
||||
List<at.procon.eventhub.dto.EventHubEventDto> events = service.loadVehicleEvents(
|
||||
UnifiedVehicleEventsRequest.forTachographFileSession(
|
||||
session.sessionId(),
|
||||
null,
|
||||
"VIN-1",
|
||||
null,
|
||||
null,
|
||||
OffsetDateTime.parse("2026-05-01T08:00:00Z"),
|
||||
OffsetDateTime.parse("2026-05-01T09:00:00Z")
|
||||
)
|
||||
);
|
||||
|
||||
assertThat(events).hasSize(4);
|
||||
assertThat(events).extracting(event -> event.occurredAt())
|
||||
.containsExactly(
|
||||
OffsetDateTime.parse("2026-05-01T08:00:00Z"),
|
||||
OffsetDateTime.parse("2026-05-01T08:30:00Z"),
|
||||
OffsetDateTime.parse("2026-05-01T08:45:00Z"),
|
||||
OffsetDateTime.parse("2026-05-01T09:00:00Z")
|
||||
);
|
||||
assertThat(events).extracting(event -> event.eventDomain())
|
||||
.containsExactly(
|
||||
EventDomain.DRIVER_CARD,
|
||||
EventDomain.DRIVER_ACTIVITY,
|
||||
EventDomain.POSITION,
|
||||
EventDomain.DRIVER_ACTIVITY
|
||||
);
|
||||
assertThat(events.get(0).lifecycle()).isEqualTo(EventLifecycle.INSERT);
|
||||
assertThat(events.get(1).lifecycle()).isEqualTo(EventLifecycle.START);
|
||||
assertThat(events.get(3).lifecycle()).isEqualTo(EventLifecycle.END);
|
||||
}
|
||||
|
||||
private DriverExtractionSession driver() {
|
||||
return new DriverExtractionSession(
|
||||
"12:123",
|
||||
new ExtractedDriver("12:123", "DRV:12:123", "Doe", "Jane", null, null, null, null, null),
|
||||
new ExtractedDriverCard("CARD:12:123", "12", "123", null, null, null, null),
|
||||
List.of(new ExtractedVehicleRegistration("12:REG-1", "VR:12:REG-1", "12", "REG-1")),
|
||||
List.of(new ExtractedVehicle("VIN-1", "VIN:VIN-1", "VIN-1")),
|
||||
List.of(new ExtractedCardVehicleUsageInterval(
|
||||
"CVU-1",
|
||||
OffsetDateTime.parse("2026-05-01T08:00:00Z"),
|
||||
OffsetDateTime.parse("2026-05-01T10:00:00Z"),
|
||||
100L,
|
||||
200L,
|
||||
"12:REG-1",
|
||||
"VIN-1",
|
||||
"vu-1"
|
||||
)),
|
||||
List.of(new ExtractedCardActivityInterval(
|
||||
"ACT-1",
|
||||
OffsetDateTime.parse("2026-05-01T08:30:00Z"),
|
||||
OffsetDateTime.parse("2026-05-01T09:00:00Z"),
|
||||
"DRIVE",
|
||||
"DRIVER",
|
||||
"INSERTED",
|
||||
"SINGLE",
|
||||
"12:REG-1",
|
||||
"VIN-1",
|
||||
"a"
|
||||
)),
|
||||
List.of(new ExtractedSupportEvent(
|
||||
"SUP-1",
|
||||
OffsetDateTime.parse("2026-05-01T08:45:00Z"),
|
||||
"POSITION",
|
||||
"POSITION_RECORDED",
|
||||
"SNAPSHOT",
|
||||
"DRIVER",
|
||||
"12:REG-1",
|
||||
"VIN-1",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
BigDecimal.valueOf(48.2082),
|
||||
BigDecimal.valueOf(16.3738),
|
||||
"AUTHENTIC",
|
||||
150L,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"raw-path"
|
||||
)),
|
||||
List.of()
|
||||
);
|
||||
}
|
||||
|
||||
private TachographFileSession session(DriverExtractionSession driver) {
|
||||
return new TachographFileSession(
|
||||
UUID.randomUUID(),
|
||||
new TachographFileSessionMetadata(
|
||||
"default",
|
||||
"legalrequirements-drivercard",
|
||||
"sample",
|
||||
"sample.ddd",
|
||||
"a",
|
||||
2,
|
||||
"42",
|
||||
"b",
|
||||
true,
|
||||
null
|
||||
),
|
||||
Map.of(driver.driverKey(), driver),
|
||||
new ExtractionStats(1, 1, 1, 1, 1, 0),
|
||||
List.of(),
|
||||
Instant.now(),
|
||||
Instant.now().plus(4, ChronoUnit.HOURS)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue