Separate source-specific ingestion modules

This commit is contained in:
trifonovt 2026-04-30 13:35:39 +02:00
parent 33f09b6455
commit 7ec0a512bd
40 changed files with 322 additions and 199 deletions

View File

@ -1,32 +1,16 @@
package at.procon.eventhub.api; package at.procon.eventhub.api;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.ConfiguredTachographImportPlanDto;
import at.procon.eventhub.dto.EventHubEventDto; import at.procon.eventhub.dto.EventHubEventDto;
import at.procon.eventhub.dto.EventHubPackageIngestRequest; import at.procon.eventhub.dto.EventHubPackageIngestRequest;
import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.SchedulerTriggerMode;
import at.procon.eventhub.dto.TachographImportRequest;
import at.procon.eventhub.dto.TachographImportRunResultDto;
import at.procon.eventhub.dto.TachographImportTriggerResultDto;
import at.procon.eventhub.dto.source.TachographActivityDto;
import at.procon.eventhub.dto.source.TelematicsPositionDto; import at.procon.eventhub.dto.source.TelematicsPositionDto;
import at.procon.eventhub.dto.source.YellowFoxD8BookingDto;
import at.procon.eventhub.service.TachographConfiguredImportPlanService;
import at.procon.eventhub.service.TachographImportExecutionService;
import at.procon.eventhub.service.TachographImportPlanService;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.camel.ProducerTemplate; import org.apache.camel.ProducerTemplate;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@ -34,26 +18,9 @@ import org.springframework.web.bind.annotation.RestController;
public class EventHubIngestionController { public class EventHubIngestionController {
private final ProducerTemplate producerTemplate; private final ProducerTemplate producerTemplate;
private final TachographImportPlanService tachographImportPlanService;
private final TachographConfiguredImportPlanService configuredImportPlanService;
private final TachographImportExecutionService tachographImportExecutionService;
public EventHubIngestionController( public EventHubIngestionController(ProducerTemplate producerTemplate) {
ProducerTemplate producerTemplate,
TachographImportPlanService tachographImportPlanService,
TachographConfiguredImportPlanService configuredImportPlanService,
TachographImportExecutionService tachographImportExecutionService
) {
this.producerTemplate = producerTemplate; this.producerTemplate = producerTemplate;
this.tachographImportPlanService = tachographImportPlanService;
this.configuredImportPlanService = configuredImportPlanService;
this.tachographImportExecutionService = tachographImportExecutionService;
}
@PostMapping("/yellowfox/d8-bookings")
public ResponseEntity<Map<String, Object>> ingestYellowFoxD8Bookings(@RequestBody List<YellowFoxD8BookingDto> bookings) {
producerTemplate.sendBody("direct:yellowfox-d8-booking-input", bookings);
return accepted(bookings.size(), "direct:yellowfox-d8-booking-input");
} }
@PostMapping("/telematics/positions") @PostMapping("/telematics/positions")
@ -62,59 +29,6 @@ public class EventHubIngestionController {
return accepted(positions.size(), "direct:telematics-position-input"); return accepted(positions.size(), "direct:telematics-position-input");
} }
@PostMapping("/tachograph/activities")
public ResponseEntity<Map<String, Object>> ingestTachographActivities(@RequestBody List<TachographActivityDto> activities) {
producerTemplate.sendBody("direct:tachograph-activity-input", activities);
return accepted(activities.size(), "direct:tachograph-activity-input");
}
@PostMapping("/tachograph/imports/plan")
public ResponseEntity<?> planTachographImport(@Valid @RequestBody TachographImportRequest request) {
return ResponseEntity.ok(tachographImportPlanService.createPlan(request));
}
@PostMapping("/tachograph/imports/start")
public ResponseEntity<TachographImportRunResultDto> startTachographImport(
@Valid @RequestBody TachographImportRequest request,
@RequestParam(defaultValue = "false") boolean execute
) {
TachographImportRunResultDto result = execute
? tachographImportExecutionService.startAndExecuteImport(request)
: producerTemplate.requestBody("direct:tachograph-import-start", request, TachographImportRunResultDto.class);
return ResponseEntity.accepted().body(result);
}
@GetMapping("/tachograph/imports/configured-plans")
public ResponseEntity<List<ConfiguredTachographImportPlanDto>> listConfiguredTachographPlans() {
return ResponseEntity.ok(configuredImportPlanService.listPlans());
}
@GetMapping("/tachograph/imports/configured-plans/{planKey}")
public ResponseEntity<ConfiguredTachographImportPlanDto> getConfiguredTachographPlan(@PathVariable String planKey) {
return ResponseEntity.ok(configuredImportPlanService.getPlan(planKey));
}
@PostMapping("/tachograph/imports/configured-plans/{planKey}/start")
public ResponseEntity<TachographImportTriggerResultDto> startConfiguredTachographPlan(
@PathVariable String planKey,
@RequestParam(required = false) ImportMode mode,
@RequestParam(required = false) AcquisitionStrategy strategy,
@RequestParam(defaultValue = "PLAN_ONLY") SchedulerTriggerMode triggerMode
) {
TachographImportRequest request = configuredImportPlanService.createRequest(planKey, mode, strategy);
TachographImportRunResultDto result = triggerMode == SchedulerTriggerMode.EXECUTE
? tachographImportExecutionService.startAndExecuteImport(request)
: tachographImportExecutionService.startImport(request);
return ResponseEntity.accepted().body(new TachographImportTriggerResultDto(
planKey,
request.mode(),
request.acquisitionStrategy(),
triggerMode,
OffsetDateTime.now(),
result
));
}
@PostMapping("/packages") @PostMapping("/packages")
public ResponseEntity<Map<String, Object>> ingestPackage(@Valid @RequestBody EventHubPackageIngestRequest request) { public ResponseEntity<Map<String, Object>> ingestPackage(@Valid @RequestBody EventHubPackageIngestRequest request) {
producerTemplate.sendBody("direct:eventhub-package-input", request); producerTemplate.sendBody("direct:eventhub-package-input", request);

View File

@ -6,8 +6,6 @@ import at.procon.eventhub.dto.EventHubPackageRequest;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto; import at.procon.eventhub.dto.SourceGroupRefDto;
import at.procon.eventhub.dto.SourcePackageRefDto; import at.procon.eventhub.dto.SourcePackageRefDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TimeChunkDto;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
@ -51,6 +49,8 @@ public class DataPackageRepository {
null, null,
null, null,
null, null,
null,
null,
metadata metadata
); );
} }
@ -60,8 +60,11 @@ public class DataPackageRepository {
int eventSourceId, int eventSourceId,
String packageKey, String packageKey,
EventHubPackageRequest packageInfo, EventHubPackageRequest packageInfo,
TachographImportPlanItemDto planItem, String extractionCode,
TimeChunkDto chunk, String extractionSourceKind,
String entityAxis,
OffsetDateTime chunkFrom,
OffsetDateTime chunkTo,
int batchNo, int batchNo,
Map<String, Object> metadata Map<String, Object> metadata
) { ) {
@ -72,12 +75,14 @@ public class DataPackageRepository {
packageInfo, packageInfo,
DataPackageType.DB_EXTRACT, DataPackageType.DB_EXTRACT,
DataPackageStatus.PLANNED, DataPackageStatus.PLANNED,
chunk == null ? null : chunk.occurredFrom(), chunkFrom,
chunk == null ? null : chunk.occurredTo(), chunkTo,
planItem, extractionCode,
extractionSourceKind,
entityAxis,
batchNo, batchNo,
chunk == null ? null : chunk.occurredFrom(), chunkFrom,
chunk == null ? null : chunk.occurredTo(), chunkTo,
null, null,
null, null,
metadata metadata
@ -93,7 +98,9 @@ public class DataPackageRepository {
DataPackageStatus status, DataPackageStatus status,
OffsetDateTime occurredFrom, OffsetDateTime occurredFrom,
OffsetDateTime occurredTo, OffsetDateTime occurredTo,
TachographImportPlanItemDto planItem, String extractionCode,
String extractionSourceKind,
String entityAxis,
Integer batchNo, Integer batchNo,
OffsetDateTime chunkFrom, OffsetDateTime chunkFrom,
OffsetDateTime chunkTo, OffsetDateTime chunkTo,
@ -145,9 +152,9 @@ public class DataPackageRepository {
ps.setString(19, packageInfo == null ? null : packageInfo.eventFamily()); ps.setString(19, packageInfo == null ? null : packageInfo.eventFamily());
ps.setObject(20, packageInfo == null ? null : packageInfo.businessDate()); ps.setObject(20, packageInfo == null ? null : packageInfo.businessDate());
ps.setString(21, packageInfo == null ? packageKey : packageInfo.externalPackageId()); ps.setString(21, packageInfo == null ? packageKey : packageInfo.externalPackageId());
ps.setString(22, planItem == null ? null : planItem.extractionCode()); ps.setString(22, extractionCode);
ps.setString(23, planItem == null ? null : planItem.sourceKind()); ps.setString(23, extractionSourceKind);
ps.setString(24, planItem == null ? null : planItem.entityAxis()); ps.setString(24, entityAxis);
ps.setObject(25, batchNo); ps.setObject(25, batchNo);
ps.setObject(26, chunkFrom); ps.setObject(26, chunkFrom);
ps.setObject(27, chunkTo); ps.setObject(27, chunkTo);

View File

@ -0,0 +1,109 @@
package at.procon.eventhub.tachograph.api;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.SchedulerTriggerMode;
import at.procon.eventhub.tachograph.dto.ConfiguredTachographImportPlanDto;
import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.tachograph.dto.TachographImportRunResultDto;
import at.procon.eventhub.tachograph.dto.TachographImportTriggerResultDto;
import at.procon.eventhub.tachograph.dto.source.TachographActivityDto;
import at.procon.eventhub.tachograph.service.TachographConfiguredImportPlanService;
import at.procon.eventhub.tachograph.service.TachographImportExecutionService;
import at.procon.eventhub.tachograph.service.TachographImportPlanService;
import jakarta.validation.Valid;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
import org.apache.camel.ProducerTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/eventhub/acquisition/tachograph")
public class TachographIngestionController {
private final ProducerTemplate producerTemplate;
private final TachographImportPlanService tachographImportPlanService;
private final TachographConfiguredImportPlanService configuredImportPlanService;
private final TachographImportExecutionService tachographImportExecutionService;
public TachographIngestionController(
ProducerTemplate producerTemplate,
TachographImportPlanService tachographImportPlanService,
TachographConfiguredImportPlanService configuredImportPlanService,
TachographImportExecutionService tachographImportExecutionService
) {
this.producerTemplate = producerTemplate;
this.tachographImportPlanService = tachographImportPlanService;
this.configuredImportPlanService = configuredImportPlanService;
this.tachographImportExecutionService = tachographImportExecutionService;
}
@PostMapping("/activities")
public ResponseEntity<Map<String, Object>> ingestTachographActivities(@RequestBody List<TachographActivityDto> activities) {
producerTemplate.sendBody("direct:tachograph-activity-input", activities);
return accepted(activities.size(), "direct:tachograph-activity-input");
}
@PostMapping("/imports/plan")
public ResponseEntity<?> planTachographImport(@Valid @RequestBody TachographImportRequest request) {
return ResponseEntity.ok(tachographImportPlanService.createPlan(request));
}
@PostMapping("/imports/start")
public ResponseEntity<TachographImportRunResultDto> startTachographImport(
@Valid @RequestBody TachographImportRequest request,
@RequestParam(defaultValue = "false") boolean execute
) {
TachographImportRunResultDto result = execute
? tachographImportExecutionService.startAndExecuteImport(request)
: producerTemplate.requestBody("direct:tachograph-import-start", request, TachographImportRunResultDto.class);
return ResponseEntity.accepted().body(result);
}
@GetMapping("/imports/configured-plans")
public ResponseEntity<List<ConfiguredTachographImportPlanDto>> listConfiguredTachographPlans() {
return ResponseEntity.ok(configuredImportPlanService.listPlans());
}
@GetMapping("/imports/configured-plans/{planKey}")
public ResponseEntity<ConfiguredTachographImportPlanDto> getConfiguredTachographPlan(@PathVariable String planKey) {
return ResponseEntity.ok(configuredImportPlanService.getPlan(planKey));
}
@PostMapping("/imports/configured-plans/{planKey}/start")
public ResponseEntity<TachographImportTriggerResultDto> startConfiguredTachographPlan(
@PathVariable String planKey,
@RequestParam(required = false) ImportMode mode,
@RequestParam(required = false) AcquisitionStrategy strategy,
@RequestParam(defaultValue = "PLAN_ONLY") SchedulerTriggerMode triggerMode
) {
TachographImportRequest request = configuredImportPlanService.createRequest(planKey, mode, strategy);
TachographImportRunResultDto result = triggerMode == SchedulerTriggerMode.EXECUTE
? tachographImportExecutionService.startAndExecuteImport(request)
: tachographImportExecutionService.startImport(request);
return ResponseEntity.accepted().body(new TachographImportTriggerResultDto(
planKey,
request.mode(),
request.acquisitionStrategy(),
triggerMode,
OffsetDateTime.now(),
result
));
}
private ResponseEntity<Map<String, Object>> accepted(int count, String route) {
return ResponseEntity.accepted().body(Map.of(
"accepted", count,
"route", route,
"note", "Events are accepted into Camel acquisition routes, grouped by EventSource/package context, sorted in each batch, and then handed to the current ingestion adapter."
));
}
}

View File

@ -1,6 +1,6 @@
package at.procon.eventhub.camel; package at.procon.eventhub.tachograph.camel;
import at.procon.eventhub.service.TachographActivityEventMapper; import at.procon.eventhub.tachograph.service.TachographActivityEventMapper;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -1,7 +1,7 @@
package at.procon.eventhub.camel; package at.procon.eventhub.tachograph.camel;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.service.TachographImportExecutionService; import at.procon.eventhub.tachograph.service.TachographImportExecutionService;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -1,5 +1,6 @@
package at.procon.eventhub.config; package at.procon.eventhub.tachograph.config;
import at.procon.eventhub.config.EventHubProperties;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;

View File

@ -1,4 +1,11 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.EventFamily;
import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.Set; import java.util.Set;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.UUID; import java.util.UUID;

View File

@ -1,4 +1,10 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,7 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.EventFamily;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,11 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.EventFamily;
import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;

View File

@ -1,4 +1,6 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import at.procon.eventhub.dto.ImportRunStatus;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;

View File

@ -1,4 +1,8 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.SchedulerTriggerMode;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.dto; package at.procon.eventhub.tachograph.dto;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.dto.source; package at.procon.eventhub.tachograph.dto.source;
import at.procon.eventhub.dto.CardSlot; import at.procon.eventhub.dto.CardSlot;
import at.procon.eventhub.dto.CardStatus; import at.procon.eventhub.dto.CardStatus;

View File

@ -1,9 +1,9 @@
package at.procon.eventhub.persistence; package at.procon.eventhub.tachograph.persistence;
import at.procon.eventhub.dto.AcquisitionStrategy; import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.EventFamily; import at.procon.eventhub.dto.EventFamily;
import at.procon.eventhub.dto.ImportCursorStateDto; import at.procon.eventhub.dto.ImportCursorStateDto;
import at.procon.eventhub.dto.TachographExtractionBatchResultDto; import at.procon.eventhub.tachograph.dto.TachographExtractionBatchResultDto;
import java.util.UUID; import java.util.UUID;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;

View File

@ -1,10 +1,10 @@
package at.procon.eventhub.persistence; package at.procon.eventhub.tachograph.persistence;
import at.procon.eventhub.dto.EventSourceDto; import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.ImportRunStatus; import at.procon.eventhub.dto.ImportRunStatus;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto; import at.procon.eventhub.dto.SourceGroupRefDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.sql.Array; import java.sql.Array;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.CardSlot; import at.procon.eventhub.dto.CardSlot;
import at.procon.eventhub.dto.CardStatus; import at.procon.eventhub.dto.CardStatus;
@ -12,6 +12,7 @@ import at.procon.eventhub.dto.EventType;
import at.procon.eventhub.dto.SourcePackageRefDto; import at.procon.eventhub.dto.SourcePackageRefDto;
import at.procon.eventhub.dto.VehicleRefDto; import at.procon.eventhub.dto.VehicleRefDto;
import at.procon.eventhub.dto.VehicleRegistrationRefDto; import at.procon.eventhub.dto.VehicleRegistrationRefDto;
import at.procon.eventhub.service.EventDetailsFactory;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;

View File

@ -1,5 +1,6 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.service.EventDetailsFactory;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;

View File

@ -1,12 +1,12 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.ImportCursorStateDto; import at.procon.eventhub.dto.ImportCursorStateDto;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.TachographExtractionBatchResultDto; import at.procon.eventhub.tachograph.dto.TachographExtractionBatchResultDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.dto.TimeChunkDto; import at.procon.eventhub.tachograph.dto.TimeChunkDto;
import at.procon.eventhub.persistence.ImportCursorRepository; import at.procon.eventhub.tachograph.persistence.ImportCursorRepository;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;

View File

@ -1,9 +1,9 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.TachographExtractionBatchResultDto; import at.procon.eventhub.tachograph.dto.TachographExtractionBatchResultDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.dto.TimeChunkDto; import at.procon.eventhub.tachograph.dto.TimeChunkDto;
import java.util.UUID; import java.util.UUID;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.EventDomain; import at.procon.eventhub.dto.EventDomain;
import at.procon.eventhub.dto.EventHubEventDto; import at.procon.eventhub.dto.EventHubEventDto;
@ -7,7 +7,8 @@ import at.procon.eventhub.dto.EventLifecycle;
import at.procon.eventhub.dto.EventSourceDto; import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.EventType; import at.procon.eventhub.dto.EventType;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.source.TachographActivityDto; import at.procon.eventhub.service.EventDetailsFactory;
import at.procon.eventhub.tachograph.dto.source.TachographActivityDto;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.UUID; import java.util.UUID;

View File

@ -1,11 +1,11 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.config.EventHubProperties; import at.procon.eventhub.config.EventHubProperties;
import at.procon.eventhub.dto.AcquisitionStrategy; import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.ConfiguredTachographImportPlanDto; import at.procon.eventhub.tachograph.dto.ConfiguredTachographImportPlanDto;
import at.procon.eventhub.dto.ImportMode; import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;

View File

@ -1,9 +1,9 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.TachographExtractionBatchResultDto; import at.procon.eventhub.tachograph.dto.TachographExtractionBatchResultDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.dto.TimeChunkDto; import at.procon.eventhub.tachograph.dto.TimeChunkDto;
import java.util.UUID; import java.util.UUID;
public interface TachographExtractionBatchExecutor { public interface TachographExtractionBatchExecutor {

View File

@ -1,10 +1,10 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.EventHubPackageRequest; import at.procon.eventhub.dto.EventHubPackageRequest;
import at.procon.eventhub.dto.EventSourceDto; import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.dto.TimeChunkDto; import at.procon.eventhub.tachograph.dto.TimeChunkDto;
import java.util.UUID; import java.util.UUID;
public record TachographExtractionContext( public record TachographExtractionContext(

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.EventFamily; import at.procon.eventhub.dto.EventFamily;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.EventFamily; import at.procon.eventhub.dto.EventFamily;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.EventHubEventDto; import at.procon.eventhub.dto.EventHubEventDto;
import java.sql.ResultSet; import java.sql.ResultSet;

View File

@ -1,19 +1,19 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.DataPackageType; import at.procon.eventhub.dto.DataPackageType;
import at.procon.eventhub.dto.EventHubPackageRequest; import at.procon.eventhub.dto.EventHubPackageRequest;
import at.procon.eventhub.dto.EventSourceDto; import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.ImportRunStatus; import at.procon.eventhub.dto.ImportRunStatus;
import at.procon.eventhub.dto.TachographExtractionBatchResultDto; import at.procon.eventhub.tachograph.dto.TachographExtractionBatchResultDto;
import at.procon.eventhub.dto.TachographImportPlanDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.dto.TachographImportRunResultDto; import at.procon.eventhub.tachograph.dto.TachographImportRunResultDto;
import at.procon.eventhub.dto.TimeChunkDto; import at.procon.eventhub.tachograph.dto.TimeChunkDto;
import at.procon.eventhub.persistence.DataPackageRepository; import at.procon.eventhub.persistence.DataPackageRepository;
import at.procon.eventhub.persistence.EventSourceRepository; import at.procon.eventhub.persistence.EventSourceRepository;
import at.procon.eventhub.persistence.ImportRunRepository; import at.procon.eventhub.tachograph.persistence.ImportCursorRepository;
import at.procon.eventhub.persistence.ImportCursorRepository; import at.procon.eventhub.tachograph.persistence.ImportRunRepository;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -98,8 +98,11 @@ public class TachographImportExecutionService {
itemEventSourceId, itemEventSourceId,
packageKey, packageKey,
packageInfo, packageInfo,
item, item.extractionCode(),
chunk, item.sourceKind(),
item.entityAxis(),
chunk == null ? null : chunk.occurredFrom(),
chunk == null ? null : chunk.occurredTo(),
batchNo, batchNo,
metadata(request, item, chunk, importRunId) metadata(request, item, chunk, importRunId)
); );

View File

@ -1,14 +1,14 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.config.EventHubProperties; import at.procon.eventhub.config.EventHubProperties;
import at.procon.eventhub.dto.AcquisitionStrategy; import at.procon.eventhub.dto.AcquisitionStrategy;
import at.procon.eventhub.dto.EventFamily; import at.procon.eventhub.dto.EventFamily;
import at.procon.eventhub.dto.ImportMode; import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.TachographImportPlanDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanDto;
import at.procon.eventhub.dto.TachographImportPlanItemDto; import at.procon.eventhub.tachograph.dto.TachographImportPlanItemDto;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import at.procon.eventhub.dto.TimeChunkDto; import at.procon.eventhub.tachograph.dto.TimeChunkDto;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -1,9 +1,9 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.config.EventHubProperties; import at.procon.eventhub.config.EventHubProperties;
import at.procon.eventhub.dto.ImportMode; import at.procon.eventhub.dto.ImportMode;
import at.procon.eventhub.dto.SchedulerTriggerMode; import at.procon.eventhub.dto.SchedulerTriggerMode;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;

View File

@ -1,6 +1,6 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.dto.TachographImportRequest; import at.procon.eventhub.tachograph.dto.TachographImportRequest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@ -1,5 +1,6 @@
package at.procon.eventhub.service; package at.procon.eventhub.tachograph.service;
import at.procon.eventhub.service.EventDetailsFactory;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;

View File

@ -0,0 +1,32 @@
package at.procon.eventhub.yellowfox.api;
import at.procon.eventhub.yellowfox.dto.YellowFoxD8BookingDto;
import java.util.List;
import java.util.Map;
import org.apache.camel.ProducerTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/eventhub/acquisition/yellowfox")
public class YellowFoxIngestionController {
private final ProducerTemplate producerTemplate;
public YellowFoxIngestionController(ProducerTemplate producerTemplate) {
this.producerTemplate = producerTemplate;
}
@PostMapping("/d8-bookings")
public ResponseEntity<Map<String, Object>> ingestYellowFoxD8Bookings(@RequestBody List<YellowFoxD8BookingDto> bookings) {
producerTemplate.sendBody("direct:yellowfox-d8-booking-input", bookings);
return ResponseEntity.accepted().body(Map.of(
"accepted", bookings.size(),
"route", "direct:yellowfox-d8-booking-input",
"note", "Events are accepted into Camel acquisition routes, grouped by EventSource/package context, sorted in each batch, and then handed to the current ingestion adapter."
));
}
}

View File

@ -1,6 +1,6 @@
package at.procon.eventhub.camel; package at.procon.eventhub.yellowfox.camel;
import at.procon.eventhub.service.YellowFoxD8BookingEventMapper; import at.procon.eventhub.yellowfox.service.YellowFoxD8BookingEventMapper;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.dto.source; package at.procon.eventhub.yellowfox.dto;
import at.procon.eventhub.dto.DriverRefDto; import at.procon.eventhub.dto.DriverRefDto;
import at.procon.eventhub.dto.VehicleRefDto; import at.procon.eventhub.dto.VehicleRefDto;

View File

@ -1,4 +1,4 @@
package at.procon.eventhub.service; package at.procon.eventhub.yellowfox.service;
import at.procon.eventhub.dto.CardSlot; import at.procon.eventhub.dto.CardSlot;
import at.procon.eventhub.dto.CardStatus; import at.procon.eventhub.dto.CardStatus;
@ -13,7 +13,8 @@ import at.procon.eventhub.dto.GeoPointDto;
import at.procon.eventhub.dto.ImportScopeDto; import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto; import at.procon.eventhub.dto.SourceGroupRefDto;
import at.procon.eventhub.dto.SourceGroupType; import at.procon.eventhub.dto.SourceGroupType;
import at.procon.eventhub.dto.source.YellowFoxD8BookingDto; import at.procon.eventhub.service.EventDetailsFactory;
import at.procon.eventhub.yellowfox.dto.YellowFoxD8BookingDto;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;

View File

@ -14,7 +14,7 @@ select
concat('TACHOGRAPH:CARD_ACTIVITY:', ca.ID) as external_source_event_id, concat('TACHOGRAPH:CARD_ACTIVITY:', ca.ID) as external_source_event_id,
ca.BeginTime as occurred_at, ca.BeginTime as occurred_at,
cast(null as datetime) as received_partner_at, coalesce(fl.DownloadDate, fl.OriginalDownloadDate, fl.TStamp, fl.CreationDate) as received_partner_at,
ca.Activity as activity_code, ca.Activity as activity_code,
ca.Activity as activity_text, ca.Activity as activity_text,
case upper(coalesce(ca.Activity, '')) case upper(coalesce(ca.Activity, ''))
@ -44,21 +44,21 @@ select
v.VRN as vehicle_registration_number, v.VRN as vehicle_registration_number,
'DRIVER_CARD' as source_package_kind, 'DRIVER_CARD' as source_package_kind,
cast(coalesce(ca.ID_FileLog, cda.ID_FileLog, c.ID_FileLog) as varchar(128)) as source_package_id, cast(coalesce(fl.ID, ca.ID_FileLog, cda.ID_FileLog, c.ID_FileLog, ca.ID) as varchar(128)) as source_package_id,
cast(c.ID as varchar(128)) as source_package_entity_id, cast(coalesce(fl.ID_Card, c.ID) as varchar(128)) as source_package_entity_id,
cda.RecordDate as source_package_period_from, coalesce(fl.DownloadFrom, cda.RecordDate) as source_package_period_from,
coalesce(cda.RecordDateTo, dateadd(day, 1, cda.RecordDate)) as source_package_period_to, coalesce(fl.DownloadTo, cda.RecordDateTo, dateadd(day, 1, cda.RecordDate)) as source_package_period_to,
cast(null as datetime) as source_package_imported_at coalesce(fl.CreationDate, fl.TStamp) as source_package_imported_at
from dbo.CardActivity ca from dbo.CardActivity ca
join dbo.CardDailyActivity cda on cda.ID = ca.ID_DailyActivity join dbo.CardDailyActivity cda on cda.ID = ca.ID_DailyActivity
join dbo.Card c on c.ID = cda.ID_Card join dbo.Card c on c.ID = cda.ID_Card
left join dbo.FileLog fl on fl.ID = coalesce(ca.ID_FileLog, cda.ID_FileLog, c.ID_FileLog)
left join dbo.Driver d on d.ID = c.ID_Driver left join dbo.Driver d on d.ID = c.ID_Driver
left join dbo.Nation cn on cn.ID = c.ID_Nation left join dbo.Nation cn on cn.ID = c.ID_Nation
outer apply ( outer apply (
select top 1 used.ID_Vehicle, select top 1 used.ID_Vehicle,
used.VIN, used.VIN,
used.OdoBegin, used.OdoBegin
used.ID_VUInstallation
from dbo.CardVehiclesUsed used from dbo.CardVehiclesUsed used
where used.ID_Card = c.ID where used.ID_Card = c.ID
and (used.FirstUse is null or used.FirstUse <= ca.BeginTime) and (used.FirstUse is null or used.FirstUse <= ca.BeginTime)
@ -73,11 +73,22 @@ left join dbo.VehicleIdentification vi on vi.ID = v.ID_VehicleIdentification
left join dbo.Nation vn on vn.ID = v.ID_Nation left join dbo.Nation vn on vn.ID = v.ID_Nation
where (:occurredFrom is null or ca.BeginTime >= :occurredFrom) where (:occurredFrom is null or ca.BeginTime >= :occurredFrom)
and (:occurredTo is null or ca.BeginTime < :occurredTo) and (:occurredTo is null or ca.BeginTime < :occurredTo)
and (
:lastSourcePackageImportedAt is null
or coalesce(fl.CreationDate, fl.TStamp) > :lastSourcePackageImportedAt
or (
coalesce(fl.CreationDate, fl.TStamp) = :lastSourcePackageImportedAt
and coalesce(fl.ID, ca.ID_FileLog, cda.ID_FileLog, c.ID_FileLog, ca.ID) > try_convert(int, :lastSourcePackageId)
)
or (
coalesce(fl.CreationDate, fl.TStamp) is null
and ( and (
:lastSourcePackageId is null :lastSourcePackageId is null
or coalesce(ca.ID_FileLog, cda.ID_FileLog, c.ID_FileLog, ca.ID) > try_convert(int, :lastSourcePackageId) or coalesce(fl.ID, ca.ID_FileLog, cda.ID_FileLog, c.ID_FileLog, ca.ID) > try_convert(int, :lastSourcePackageId)
)
)
) )
/* /*
* Organisation filtering can be added through Driver_I_90021 / Vehicle_I_90021 * Organisation filtering can use FileLog.I_90021_ID / FileLog.OrgID or
* once the exact organisation subtree semantics are confirmed. * Driver_I_90021 / Vehicle_I_90021 once subtree semantics are confirmed.
*/ */

View File

@ -11,7 +11,7 @@ select
concat('TACHOGRAPH:VU_ACTIVITY:', va.ID) as external_source_event_id, concat('TACHOGRAPH:VU_ACTIVITY:', va.ID) as external_source_event_id,
va.BeginTime as occurred_at, va.BeginTime as occurred_at,
cast(null as datetime) as received_partner_at, coalesce(fl.DownloadDate, fl.OriginalDownloadDate, fl.TStamp, fl.CreationDate) as received_partner_at,
va.Activity as activity_code, va.Activity as activity_code,
va.Activity as activity_text, va.Activity as activity_text,
case upper(coalesce(va.Activity, '')) case upper(coalesce(va.Activity, ''))
@ -41,14 +41,15 @@ select
v.VRN as vehicle_registration_number, v.VRN as vehicle_registration_number,
'VEHICLE_UNIT' as source_package_kind, 'VEHICLE_UNIT' as source_package_kind,
cast(coalesce(va.ID_FileLog, vda.ID_FileLog, vui.ID_FileLog) as varchar(128)) as source_package_id, cast(coalesce(fl.ID, va.ID_FileLog, vda.ID_FileLog, vui.ID_FileLog, va.ID) as varchar(128)) as source_package_id,
cast(vui.ID_VehicleIdentification as varchar(128)) as source_package_entity_id, cast(coalesce(fl.ID_VehicleIdentification, vui.ID_VehicleIdentification) as varchar(128)) as source_package_entity_id,
vda.RecordDate as source_package_period_from, coalesce(fl.DownloadFrom, vda.RecordDate) as source_package_period_from,
dateadd(day, 1, vda.RecordDate) as source_package_period_to, coalesce(fl.DownloadTo, dateadd(day, 1, vda.RecordDate)) as source_package_period_to,
cast(null as datetime) as source_package_imported_at coalesce(fl.CreationDate, fl.TStamp) as source_package_imported_at
from dbo.VUActivity va from dbo.VUActivity va
join dbo.VUDailyActivity vda on vda.ID = va.ID_VUDailyActivity join dbo.VUDailyActivity vda on vda.ID = va.ID_VUDailyActivity
join dbo.VUInstallation vui on vui.ID = vda.ID_VUInstallation join dbo.VUInstallation vui on vui.ID = vda.ID_VUInstallation
left join dbo.FileLog fl on fl.ID = coalesce(va.ID_FileLog, vda.ID_FileLog, vui.ID_FileLog)
join dbo.VehicleIdentification vi on vi.ID = vui.ID_VehicleIdentification join dbo.VehicleIdentification vi on vi.ID = vui.ID_VehicleIdentification
outer apply ( outer apply (
select top 1 vehicle.ID, select top 1 vehicle.ID,
@ -70,11 +71,22 @@ left join dbo.Driver d on d.ID = c.ID_Driver
left join dbo.Nation cn on cn.ID = c.ID_Nation left join dbo.Nation cn on cn.ID = c.ID_Nation
where (:occurredFrom is null or va.BeginTime >= :occurredFrom) where (:occurredFrom is null or va.BeginTime >= :occurredFrom)
and (:occurredTo is null or va.BeginTime < :occurredTo) and (:occurredTo is null or va.BeginTime < :occurredTo)
and (
:lastSourcePackageImportedAt is null
or coalesce(fl.CreationDate, fl.TStamp) > :lastSourcePackageImportedAt
or (
coalesce(fl.CreationDate, fl.TStamp) = :lastSourcePackageImportedAt
and coalesce(fl.ID, va.ID_FileLog, vda.ID_FileLog, vui.ID_FileLog, va.ID) > try_convert(int, :lastSourcePackageId)
)
or (
coalesce(fl.CreationDate, fl.TStamp) is null
and ( and (
:lastSourcePackageId is null :lastSourcePackageId is null
or coalesce(va.ID_FileLog, vda.ID_FileLog, vui.ID_FileLog, va.ID) > try_convert(int, :lastSourcePackageId) or coalesce(fl.ID, va.ID_FileLog, vda.ID_FileLog, vui.ID_FileLog, va.ID) > try_convert(int, :lastSourcePackageId)
)
)
) )
/* /*
* Organisation filtering can be added through Vehicle_I_90021 / Driver_I_90021 * Organisation filtering can use FileLog.I_90021_ID / FileLog.OrgID or
* once the exact organisation subtree semantics are confirmed. * Vehicle_I_90021 / Driver_I_90021 once subtree semantics are confirmed.
*/ */

View File

@ -7,9 +7,9 @@ import at.procon.eventhub.dto.EventLifecycle;
import at.procon.eventhub.dto.EventType; import at.procon.eventhub.dto.EventType;
import at.procon.eventhub.dto.VehicleRefDto; import at.procon.eventhub.dto.VehicleRefDto;
import at.procon.eventhub.dto.VehicleRegistrationRefDto; import at.procon.eventhub.dto.VehicleRegistrationRefDto;
import at.procon.eventhub.dto.source.YellowFoxD8BookingDto; import at.procon.eventhub.yellowfox.dto.YellowFoxD8BookingDto;
import at.procon.eventhub.service.EventDetailsFactory; import at.procon.eventhub.service.EventDetailsFactory;
import at.procon.eventhub.service.YellowFoxD8BookingEventMapper; import at.procon.eventhub.yellowfox.service.YellowFoxD8BookingEventMapper;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;