perf(firstleg): scope appointment fact source aggregation by container
This commit is contained in:
+13
-3
@@ -18,15 +18,25 @@ class AppointmentWorkSourceMapperTest {
|
||||
s.execute("CREATE TABLE fl_direct_delivery_unloading(container_booking_id BIGINT)");
|
||||
s.execute("INSERT INTO fl_container_booking VALUES(1,'D1',NULL,'上海',NULL,1,'ACTIVE'),(2,'D2','C2','上海','私人仓',1,'ACTIVE'),(3,'D3','C3','上海',NULL,1,'ACTIVE'),(4,'D4','C4','上海',NULL,1,'MERGED')");
|
||||
s.execute("INSERT INTO fl_carrier_schedule_node_fact VALUES(10,1,'DEPARTED_ORIGIN_PORT','2026-10-01'),(20,2,'EMPTY_RETURNED','2026-10-03'),(30,3,'LOADED_ON_VESSEL','2026-10-04'),(40,4,'DEPARTED_ORIGIN_PORT','2026-10-01'),(50,3,'DEPARTED_ORIGIN_PORT',NULL)");
|
||||
s.execute("INSERT INTO fl_direct_delivery_unloading VALUES(2)");
|
||||
s.execute("INSERT INTO fl_direct_delivery_unloading VALUES(2),(2)");
|
||||
s.execute("INSERT INTO fl_carrier_schedule_node_fact VALUES(60,1,'IN_TRANSIT','2026-10-02'),(70,1,'ARRIVED_DESTINATION_PORT','2026-10-03'),(80,2,'EMPTY_RETURNED',NULL)");
|
||||
}
|
||||
var config=new MybatisConfiguration();config.setMapUnderscoreToCamelCase(true);
|
||||
config.setEnvironment(new Environment("test",new JdbcTransactionFactory(),ds));config.addMapper(AppointmentWorkSourceMapper.class);
|
||||
try(var session=new MybatisSqlSessionFactoryBuilder().build(config).openSession()) {
|
||||
var rows=session.getMapper(AppointmentWorkSourceMapper.class).sources();
|
||||
var mapper=session.getMapper(AppointmentWorkSourceMapper.class);
|
||||
var rows=mapper.sources();
|
||||
assertEquals(2,rows.size());assertEquals(1,rows.get(0).id());assertEquals(2,rows.get(1).id());
|
||||
assertNull(rows.get(0).destinationWarehouseName());assertEquals(1,rows.get(1).deliveryVersion());
|
||||
assertNull(rows.get(0).destinationWarehouseName());assertEquals(2,rows.get(1).deliveryVersion());
|
||||
assertNull(rows.get(1).departedLocalAt());assertNotNull(rows.get(1).sailedEvidenceLocalAt());
|
||||
assertEquals(70,rows.get(0).factVersion());assertEquals(20,rows.get(1).factVersion());
|
||||
// The optimized path must equal the former full-manifest + Java filter, including
|
||||
// dates, versions, null names, unloading counts, duplicate IDs and ineligible sources.
|
||||
for(var ids:java.util.List.of(java.util.List.of(2L,1L),java.util.List.of(1L,1L),
|
||||
java.util.List.of(2L,3L,4L,999L),java.util.List.of(3L,4L),java.util.List.<Long>of())) {
|
||||
assertEquals(rows.stream().filter(row->ids.contains(row.id())).toList(),mapper.sourcesByIds(ids));
|
||||
}
|
||||
assertTrue(mapper.sourcesByIds(null).isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -52,8 +52,8 @@ class AppointmentWorkSourceServiceTest {
|
||||
when(mapper.sources()).thenReturn(List.of(source(1,1)));
|
||||
assertEquals(503,assertThrows(ResponseStatusException.class,()->service.container(1)).getStatusCode().value());
|
||||
}
|
||||
@Test void factBatchReadsManifestOnceAndPreservesEachContainerIdentity() {
|
||||
when(mapper.sources()).thenReturn(IntStream.rangeClosed(1,100).mapToObj(id->source(id,1)).toList());
|
||||
@Test void factBatchReadsOnlyRequestedSourcesAndPreservesEachContainerIdentity() {
|
||||
when(mapper.sourcesByIds(anyList())).thenReturn(IntStream.rangeClosed(1,100).mapToObj(id->source(id,1)).toList());
|
||||
when(mapper.cargo(anyList())).thenReturn(List.of());
|
||||
stubFlows("UNKNOWN");
|
||||
var fact=mock(Fact.class);
|
||||
@@ -66,19 +66,21 @@ class AppointmentWorkSourceServiceTest {
|
||||
var requests=IntStream.rangeClosed(1,100).boxed().flatMap(id->List.of(
|
||||
request("PICKUP-"+id,"PICKUP",id),request("RETURN-"+id,"EMPTY_RETURN",id)).stream()).toList();
|
||||
assertEquals(200,service.facts(requests).size());
|
||||
verify(mapper,times(1)).sources();
|
||||
verify(mapper,times(1)).sourcesByIds(IntStream.rangeClosed(1,100).mapToObj(Long::valueOf).toList());
|
||||
verify(mapper,never()).sources();
|
||||
verify(mapper,times(1)).cargo(IntStream.rangeClosed(1,100).mapToObj(Long::valueOf).toList());
|
||||
verify(facts,times(1)).establishedFlows(anyList());
|
||||
verify(facts,times(1)).read(any(),any());
|
||||
}
|
||||
@Test void nextFactBatchReadsFreshManifestAndRejectsRemovedContainer() {
|
||||
when(mapper.sources()).thenReturn(List.of(source(1,1)),List.of());
|
||||
@Test void nextFactBatchReadsFreshSourcesAndRejectsRemovedContainer() {
|
||||
when(mapper.sourcesByIds(List.of(1L))).thenReturn(List.of(source(1,1)),List.of());
|
||||
when(mapper.cargo(List.of(1L))).thenReturn(List.of());
|
||||
stubFlows("UNKNOWN");
|
||||
var request=request("PICKUP-1","PICKUP",1);
|
||||
service.facts(List.of(request));
|
||||
assertEquals(404,assertThrows(ResponseStatusException.class,()->service.facts(List.of(request))).getStatusCode().value());
|
||||
verify(mapper,times(2)).sources();
|
||||
verify(mapper,times(2)).sourcesByIds(List.of(1L));
|
||||
verify(mapper,never()).sources();
|
||||
verify(facts,times(1)).read(any(),any());
|
||||
}
|
||||
private void stubFlows(String flow) {
|
||||
|
||||
Reference in New Issue
Block a user