Commit remaining tracked non-log changes

This commit is contained in:
trifonovt 2026-05-22 15:45:43 +02:00
parent 1128bd3f56
commit dd9c33c5fd
8 changed files with 266 additions and 69 deletions

View File

@ -69,6 +69,10 @@
<groupId>org.apache.camel.springboot</groupId> <groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId> <artifactId>camel-jackson-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.flywaydb</groupId> <groupId>org.flywaydb</groupId>

View File

@ -631,6 +631,121 @@
} }
} }
] ]
},
{
"name": "Tachograph composite sessions",
"item": [
{
"name": "Create tachograph composite session",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"sessionIds\": [\n \"{{sessionId}}\",\n \"{{additionalSessionId}}\"\n ],\n \"label\": \"{{compositeSessionLabel}}\"\n}"
},
"url": {
"raw": "{{baseUrl}}/api/eventhub/tachograph-composite-sessions",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"eventhub",
"tachograph-composite-sessions"
]
}
}
},
{
"name": "Get tachograph composite session",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/api/eventhub/tachograph-composite-sessions/{{compositeSessionId}}",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"eventhub",
"tachograph-composite-sessions",
"{{compositeSessionId}}"
]
}
}
},
{
"name": "List tachograph composite session drivers",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/api/eventhub/tachograph-composite-sessions/{{compositeSessionId}}/drivers",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"eventhub",
"tachograph-composite-sessions",
"{{compositeSessionId}}",
"drivers"
]
}
}
},
{
"name": "Load tachograph composite driver events",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/api/eventhub/tachograph-composite-sessions/{{compositeSessionId}}/drivers/{{driverKey}}/events",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"eventhub",
"tachograph-composite-sessions",
"{{compositeSessionId}}",
"drivers",
"{{driverKey}}",
"events"
]
}
}
},
{
"name": "Load tachograph composite driver timeline",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/api/eventhub/tachograph-composite-sessions/{{compositeSessionId}}/drivers/{{driverKey}}/timeline",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"eventhub",
"tachograph-composite-sessions",
"{{compositeSessionId}}",
"drivers",
"{{driverKey}}",
"timeline"
]
}
}
}
]
} }
], ],
"variable": [ "variable": [
@ -670,6 +785,18 @@
"key": "sessionId", "key": "sessionId",
"value": "00000000-0000-0000-0000-000000000000" "value": "00000000-0000-0000-0000-000000000000"
}, },
{
"key": "additionalSessionId",
"value": "00000000-0000-0000-0000-000000000001"
},
{
"key": "compositeSessionId",
"value": "00000000-0000-0000-0000-000000000100"
},
{
"key": "compositeSessionLabel",
"value": "driver-multi-file sample"
},
{ {
"key": "driverKey", "key": "driverKey",
"value": "12:12345678901200" "value": "12:12345678901200"

View File

@ -1,6 +1,8 @@
package at.procon.eventhub.config; package at.procon.eventhub.config;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -11,7 +13,9 @@ public class JacksonConfig {
@Bean @Bean
@ConditionalOnMissingBean(ObjectMapper.class) @ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper objectMapper() { public ObjectMapper objectMapper() {
return new ObjectMapper().findAndRegisterModules(); return new ObjectMapper()
.registerModule(new JavaTimeModule())
.findAndRegisterModules()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
} }
} }

View File

@ -442,16 +442,34 @@ public class EventHubEventReadRepository {
return Integer.parseInt(value.toString()); return Integer.parseInt(value.toString());
} }
private JsonNode json(String value) { static JsonNode parseJsonColumn(ObjectMapper objectMapper, String value) {
try { try {
return value == null || value.isBlank() JsonNode node = value == null || value.isBlank()
? objectMapper.createObjectNode() ? objectMapper.createObjectNode()
: objectMapper.readTree(value); : objectMapper.readTree(value);
while (node != null
&& node.isTextual()
&& looksLikeEmbeddedJson(node.textValue())) {
node = objectMapper.readTree(node.textValue());
}
return node;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to parse JSON column.", e); throw new IllegalArgumentException("Failed to parse JSON column.", e);
} }
} }
private JsonNode json(String value) {
return parseJsonColumn(objectMapper, value);
}
private static boolean looksLikeEmbeddedJson(String value) {
if (value == null) {
return false;
}
String trimmed = value.trim();
return trimmed.startsWith("{") || trimmed.startsWith("[");
}
private String syntheticId(String prefix, UUID id) { private String syntheticId(String prefix, UUID id) {
return id == null ? null : prefix + ":" + id; return id == null ? null : prefix + ":" + id;
} }

View File

@ -1,8 +1,10 @@
package at.procon.eventhub.tachographfilesession.api; package at.procon.eventhub.tachographfilesession.api;
import at.procon.eventhub.tachographfilesession.service.DriverNotFoundInSessionException; import at.procon.eventhub.tachographfilesession.service.DriverNotFoundInSessionException;
import at.procon.eventhub.tachographfilesession.service.DriverNotFoundInCompositeSessionException;
import at.procon.eventhub.tachographfilesession.service.LegalRequirementsUploadException; import at.procon.eventhub.tachographfilesession.service.LegalRequirementsUploadException;
import at.procon.eventhub.tachographfilesession.service.LegalRequirementsXmlDownloadException; import at.procon.eventhub.tachographfilesession.service.LegalRequirementsXmlDownloadException;
import at.procon.eventhub.tachographfilesession.service.TachographCompositeSessionNotFoundException;
import at.procon.eventhub.tachographfilesession.service.TachographFileSessionNotFoundException; import at.procon.eventhub.tachographfilesession.service.TachographFileSessionNotFoundException;
import at.procon.eventhub.tachographfilesession.service.TachographXmlValidationException; import at.procon.eventhub.tachographfilesession.service.TachographXmlValidationException;
import at.procon.eventhub.tachographfilesession.service.UnsupportedTachographFileTypeException; import at.procon.eventhub.tachographfilesession.service.UnsupportedTachographFileTypeException;
@ -13,12 +15,17 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice(basePackageClasses = TachographFileSessionController.class) @RestControllerAdvice(basePackageClasses = {
TachographFileSessionController.class,
TachographCompositeSessionController.class
})
public class TachographFileSessionExceptionHandler { public class TachographFileSessionExceptionHandler {
@ExceptionHandler({ @ExceptionHandler({
TachographFileSessionNotFoundException.class, TachographFileSessionNotFoundException.class,
DriverNotFoundInSessionException.class TachographCompositeSessionNotFoundException.class,
DriverNotFoundInSessionException.class,
DriverNotFoundInCompositeSessionException.class
}) })
public ResponseEntity<Map<String, Object>> notFound(RuntimeException exception) { public ResponseEntity<Map<String, Object>> notFound(RuntimeException exception) {
return error(HttpStatus.NOT_FOUND, exception); return error(HttpStatus.NOT_FOUND, exception);

View File

@ -130,6 +130,7 @@ eventhub:
significant-driving-minutes: 3 significant-driving-minutes: 3
merge-gap-seconds: 0 merge-gap-seconds: 0
gap-detection-tolerance-seconds: 0 gap-detection-tolerance-seconds: 0
timeline-input-mode: events
legal-requirements: legal-requirements:
base-url: ${LEGAL_REQUIREMENTS_BASE_URL:https://legalrequirements.services.bytebar.eu/ODataV4/LR} base-url: ${LEGAL_REQUIREMENTS_BASE_URL:https://legalrequirements.services.bytebar.eu/ODataV4/LR}
username: ${LEGAL_REQUIREMENTS_USERNAME:} username: ${LEGAL_REQUIREMENTS_USERNAME:}

View File

@ -1,60 +1,60 @@
ID;Name;AlphaCode;NumericCode;DefaultLanguageCode;ID_Certificate;ID_FileLog ID;Name;AlphaCode;NumericCode
0;Unknown 0;0;0;NULL;NULL;NULL 0;Unknown 0;0;0
1;Austria;A;1;de-AT;NULL;NULL 1;Austria;A;1
2;Albania;AL;2;sq-AL;NULL;NULL 2;Albania;AL;2
3;Andorra;AND;3;ca;NULL;NULL 3;Andorra;AND;3
4;Armenia;ARM;4;hy-AM;NULL;NULL 4;Armenia;ARM;4
5;Azerbaijan;AZ;5;az;NULL;NULL 5;Azerbaijan;AZ;5
6;Belgium;B;6;NULL;NULL;NULL 6;Belgium;B;6
7;Bulgaria;BG;7;bg-BG;NULL;NULL 7;Bulgaria;BG;7
8;Bosnia Herzegovina;BIH;8;NULL;NULL;NULL 8;Bosnia Herzegovina;BIH;8
9;Belarus;BY;9;be-BY;NULL;NULL 9;Belarus;BY;9
10;Switzerland;CH;10;de-CH;NULL;NULL 10;Switzerland;CH;10
11;Cyprus;CY;11;NULL;NULL;NULL 11;Cyprus;CY;11
12;Czech Republic;CZ;12;cs-CZ;NULL;NULL 12;Czech Republic;CZ;12
13;Germany;D;13;de-DE;NULL;NULL 13;Germany;D;13
14;Denmark;DK;14;da-DK;NULL;NULL 14;Denmark;DK;14
15;Spain;E;15;es-ES;NULL;NULL 15;Spain;E;15
16;Estonia;EST;16;et-EE;NULL;NULL 16;Estonia;EST;16
17;France;F;17;fr-FR;NULL;NULL 17;France;F;17
18;Finland;FIN;18;fi-FI;NULL;NULL 18;Finland;FIN;18
19;Liechtenstein;FL;19;de-LI;NULL;NULL 19;Liechtenstein;FL;19
20;Faroe Islands;FR;20;fo-FO;NULL;NULL 20;Faroe Islands;FR;20
21;United Kingdom;UK;21;en-GB;NULL;NULL 21;United Kingdom;UK;21
22;Georgia;GE;22;ka-GE;NULL;NULL 22;Georgia;GE;22
23;Greece;GR;23;el-GR;NULL;NULL 23;Greece;GR;23
24;Hungary;H;24;hu-HU;NULL;NULL 24;Hungary;H;24
25;Croatia;HR;25;hr-HR;NULL;NULL 25;Croatia;HR;25
26;Italy;I;26;it-IT;NULL;NULL 26;Italy;I;26
27;Ireland;IRL;27;en-IE;NULL;NULL 27;Ireland;IRL;27
28;Iceland;IS;28;is-IS;NULL;NULL 28;Iceland;IS;28
29;Kazakhstan;KZ;29;kk-KZ;NULL;NULL 29;Kazakhstan;KZ;29
30;Luxembourg;L;30;de-LU;NULL;NULL 30;Luxembourg;L;30
31;Lithuania;LT;31;lt-LT;NULL;NULL 31;Lithuania;LT;31
32;Latvia;LV;32;lv-LV;NULL;NULL 32;Latvia;LV;32
33;Malta;M;33;NULL;NULL;NULL 33;Malta;M;33
34;Monaco;MC;34;fr-MC;NULL;NULL 34;Monaco;MC;34
35;Moldova;MD;35;ro;NULL;NULL 35;Moldova;MD;35
36;North Macedonia;MK;36;mk-MK;NULL;NULL 36;North Macedonia;MK;36
37;Norway;N;37;no;NULL;NULL 37;Norway;N;37
38;Netherlands;NL;38;nl-NL;NULL;NULL 38;Netherlands;NL;38
39;Portugal;P;39;pt-PT;NULL;NULL 39;Portugal;P;39
40;Poland;PL;40;pl-PL;NULL;NULL 40;Poland;PL;40
41;Romania;RO;41;ro-RO;NULL;NULL 41;Romania;RO;41
42;San Marino;RSM;42;it-IT;NULL;NULL 42;San Marino;RSM;42
43;Russia;RUS;43;ru-RU;NULL;NULL 43;Russia;RUS;43
44;Sweden;S;44;sv-SE;NULL;NULL 44;Sweden;S;44
45;Slovakia;SK;45;sk-SK;NULL;NULL 45;Slovakia;SK;45
46;Slovenia;SLO;46;sl-SI;NULL;NULL 46;Slovenia;SLO;46
47;Turkmenistan;TM;47;NULL;NULL;NULL 47;Turkmenistan;TM;47
48;Turkey;TR;48;tr-TR;NULL;NULL 48;Turkey;TR;48
49;Ukraine;UA;49;uk-UA;NULL;NULL 49;Ukraine;UA;49
50;Vatican City;V;50;it-IT;NULL;NULL 50;Vatican City;V;50
51;Yugoslavia;YU;51;NULL;NULL;NULL 51;Yugoslavia;YU;51
52;Montenegro;MNE;52;NULL;NULL;763087 52;Montenegro;MNE;52
53;Serbia;SRB;53;NULL;NULL;272576 53;Serbia;SRB;53
54;Uzbekistan;UZ;54;NULL;NULL;308001 54;Uzbekistan;UZ;54
55;Tajikistan;TJ;55;NULL;NULL;NULL 55;Tajikistan;TJ;55
253;European Community;EC;253;NULL;NULL;NULL 253;European Community;EC;253
254;Rest of Europe;EUR;254;NULL;NULL;NULL 254;Rest of Europe;EUR;254
255;Rest of the world;WLD;255;NULL;NULL;NULL 255;Rest of the world;WLD;255

1 ID Name AlphaCode NumericCode DefaultLanguageCode ID_Certificate ID_FileLog
2 0 Unknown 0 0 0 NULL NULL NULL
3 1 Austria A 1 de-AT NULL NULL
4 2 Albania AL 2 sq-AL NULL NULL
5 3 Andorra AND 3 ca NULL NULL
6 4 Armenia ARM 4 hy-AM NULL NULL
7 5 Azerbaijan AZ 5 az NULL NULL
8 6 Belgium B 6 NULL NULL NULL
9 7 Bulgaria BG 7 bg-BG NULL NULL
10 8 Bosnia Herzegovina BIH 8 NULL NULL NULL
11 9 Belarus BY 9 be-BY NULL NULL
12 10 Switzerland CH 10 de-CH NULL NULL
13 11 Cyprus CY 11 NULL NULL NULL
14 12 Czech Republic CZ 12 cs-CZ NULL NULL
15 13 Germany D 13 de-DE NULL NULL
16 14 Denmark DK 14 da-DK NULL NULL
17 15 Spain E 15 es-ES NULL NULL
18 16 Estonia EST 16 et-EE NULL NULL
19 17 France F 17 fr-FR NULL NULL
20 18 Finland FIN 18 fi-FI NULL NULL
21 19 Liechtenstein FL 19 de-LI NULL NULL
22 20 Faroe Islands FR 20 fo-FO NULL NULL
23 21 United Kingdom UK 21 en-GB NULL NULL
24 22 Georgia GE 22 ka-GE NULL NULL
25 23 Greece GR 23 el-GR NULL NULL
26 24 Hungary H 24 hu-HU NULL NULL
27 25 Croatia HR 25 hr-HR NULL NULL
28 26 Italy I 26 it-IT NULL NULL
29 27 Ireland IRL 27 en-IE NULL NULL
30 28 Iceland IS 28 is-IS NULL NULL
31 29 Kazakhstan KZ 29 kk-KZ NULL NULL
32 30 Luxembourg L 30 de-LU NULL NULL
33 31 Lithuania LT 31 lt-LT NULL NULL
34 32 Latvia LV 32 lv-LV NULL NULL
35 33 Malta M 33 NULL NULL NULL
36 34 Monaco MC 34 fr-MC NULL NULL
37 35 Moldova MD 35 ro NULL NULL
38 36 North Macedonia MK 36 mk-MK NULL NULL
39 37 Norway N 37 no NULL NULL
40 38 Netherlands NL 38 nl-NL NULL NULL
41 39 Portugal P 39 pt-PT NULL NULL
42 40 Poland PL 40 pl-PL NULL NULL
43 41 Romania RO 41 ro-RO NULL NULL
44 42 San Marino RSM 42 it-IT NULL NULL
45 43 Russia RUS 43 ru-RU NULL NULL
46 44 Sweden S 44 sv-SE NULL NULL
47 45 Slovakia SK 45 sk-SK NULL NULL
48 46 Slovenia SLO 46 sl-SI NULL NULL
49 47 Turkmenistan TM 47 NULL NULL NULL
50 48 Turkey TR 48 tr-TR NULL NULL
51 49 Ukraine UA 49 uk-UA NULL NULL
52 50 Vatican City V 50 it-IT NULL NULL
53 51 Yugoslavia YU 51 NULL NULL NULL
54 52 Montenegro MNE 52 NULL NULL 763087
55 53 Serbia SRB 53 NULL NULL 272576
56 54 Uzbekistan UZ 54 NULL NULL 308001
57 55 Tajikistan TJ 55 NULL NULL NULL
58 253 European Community EC 253 NULL NULL NULL
59 254 Rest of Europe EUR 254 NULL NULL NULL
60 255 Rest of the world WLD 255 NULL NULL NULL

View File

@ -6,6 +6,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import at.procon.eventhub.dto.EventDetailsDto;
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;
@ -23,21 +24,32 @@ import at.procon.eventhub.processing.service.UnifiedRuntimeEventAssemblyService;
import at.procon.eventhub.tachographfilesession.model.ResolvedActivityInterval; import at.procon.eventhub.tachographfilesession.model.ResolvedActivityInterval;
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 com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders;
class UnifiedRuntimeProcessingControllerTest { class UnifiedRuntimeProcessingControllerTest {
private final ObjectMapper objectMapper = testObjectMapper();
@Test @Test
void loadsDriverEventsViaRuntimeApi() throws Exception { void loadsDriverEventsViaRuntimeApi() throws Exception {
UnifiedRuntimeEventAssemblyService eventAssemblyService = org.mockito.Mockito.mock(UnifiedRuntimeEventAssemblyService.class); UnifiedRuntimeEventAssemblyService eventAssemblyService = org.mockito.Mockito.mock(UnifiedRuntimeEventAssemblyService.class);
UnifiedRuntimeDriverTimelineService timelineService = org.mockito.Mockito.mock(UnifiedRuntimeDriverTimelineService.class); UnifiedRuntimeDriverTimelineService timelineService = org.mockito.Mockito.mock(UnifiedRuntimeDriverTimelineService.class);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new UnifiedRuntimeProcessingController(eventAssemblyService, timelineService)) MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new UnifiedRuntimeProcessingController(eventAssemblyService, timelineService))
.setMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper))
.setControllerAdvice(new UnifiedRuntimeProcessingExceptionHandler()) .setControllerAdvice(new UnifiedRuntimeProcessingExceptionHandler())
.build(); .build();
@ -77,7 +89,9 @@ class UnifiedRuntimeProcessingControllerTest {
.andExpect(jsonPath("$.request.sessionId").value(sessionId.toString())) .andExpect(jsonPath("$.request.sessionId").value(sessionId.toString()))
.andExpect(jsonPath("$.request.driverKey").value("12:123")) .andExpect(jsonPath("$.request.driverKey").value("12:123"))
.andExpect(jsonPath("$.discoveredVehicles[0].vin").value("VIN-1")) .andExpect(jsonPath("$.discoveredVehicles[0].vin").value("VIN-1"))
.andExpect(jsonPath("$.mergedEvents[0].externalSourceEventId").value("EV-1")); .andExpect(jsonPath("$.mergedEvents[0].externalSourceEventId").value("EV-1"))
.andExpect(jsonPath("$.mergedEvents[0].payload.raw.driverKey").value("12:123"))
.andExpect(jsonPath("$.mergedEvents[0].eventDetails.attributes.cardSlot").value("DRIVER"));
} }
@Test @Test
@ -85,6 +99,7 @@ class UnifiedRuntimeProcessingControllerTest {
UnifiedRuntimeEventAssemblyService eventAssemblyService = org.mockito.Mockito.mock(UnifiedRuntimeEventAssemblyService.class); UnifiedRuntimeEventAssemblyService eventAssemblyService = org.mockito.Mockito.mock(UnifiedRuntimeEventAssemblyService.class);
UnifiedRuntimeDriverTimelineService timelineService = org.mockito.Mockito.mock(UnifiedRuntimeDriverTimelineService.class); UnifiedRuntimeDriverTimelineService timelineService = org.mockito.Mockito.mock(UnifiedRuntimeDriverTimelineService.class);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new UnifiedRuntimeProcessingController(eventAssemblyService, timelineService)) MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new UnifiedRuntimeProcessingController(eventAssemblyService, timelineService))
.setMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper))
.setControllerAdvice(new UnifiedRuntimeProcessingExceptionHandler()) .setControllerAdvice(new UnifiedRuntimeProcessingExceptionHandler())
.build(); .build();
@ -152,6 +167,7 @@ class UnifiedRuntimeProcessingControllerTest {
UnifiedRuntimeEventAssemblyService eventAssemblyService = org.mockito.Mockito.mock(UnifiedRuntimeEventAssemblyService.class); UnifiedRuntimeEventAssemblyService eventAssemblyService = org.mockito.Mockito.mock(UnifiedRuntimeEventAssemblyService.class);
UnifiedRuntimeDriverTimelineService timelineService = org.mockito.Mockito.mock(UnifiedRuntimeDriverTimelineService.class); UnifiedRuntimeDriverTimelineService timelineService = org.mockito.Mockito.mock(UnifiedRuntimeDriverTimelineService.class);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new UnifiedRuntimeProcessingController(eventAssemblyService, timelineService)) MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new UnifiedRuntimeProcessingController(eventAssemblyService, timelineService))
.setMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper))
.setControllerAdvice(new UnifiedRuntimeProcessingExceptionHandler()) .setControllerAdvice(new UnifiedRuntimeProcessingExceptionHandler())
.build(); .build();
@ -182,11 +198,31 @@ class UnifiedRuntimeProcessingControllerTest {
EventLifecycle.START, EventLifecycle.START,
null, null,
null, null,
new EventDetailsDto("DRIVER_ACTIVITY", objectMapper.valueToTree(Map.of("cardSlot", "DRIVER"))),
null, null,
null, objectMapper.valueToTree(Map.of("raw", Map.of("driverKey", "12:123", "intervalId", "ACT-1"))),
null,
false, false,
null null
); );
} }
private ObjectMapper testObjectMapper() {
SimpleModule module = new SimpleModule();
module.addSerializer(OffsetDateTime.class, new StdScalarSerializer<>(OffsetDateTime.class) {
@Override
public void serialize(OffsetDateTime value, JsonGenerator gen, com.fasterxml.jackson.databind.SerializerProvider provider)
throws java.io.IOException {
gen.writeString(value == null ? null : value.toString());
}
});
module.addDeserializer(OffsetDateTime.class, new StdScalarDeserializer<>(OffsetDateTime.class) {
@Override
public OffsetDateTime deserialize(JsonParser p, com.fasterxml.jackson.databind.DeserializationContext ctxt)
throws java.io.IOException {
String value = p.getValueAsString();
return value == null || value.isBlank() ? null : OffsetDateTime.parse(value);
}
});
return new ObjectMapper().registerModule(module);
}
} }