11package io .kafbat .ui .service ;
22
3+ import static org .apache .kafka .common .config .TopicConfig .CLEANUP_POLICY_CONFIG ;
34import static org .assertj .core .api .Assertions .assertThat ;
45import static org .mockito .ArgumentMatchers .any ;
56import static org .mockito .ArgumentMatchers .anyBoolean ;
67import static org .mockito .ArgumentMatchers .anyList ;
78import static org .mockito .ArgumentMatchers .isA ;
8- import static org .mockito .ArgumentMatchers .isNull ;
99import static org .mockito .Mockito .mock ;
1010import static org .mockito .Mockito .when ;
1111
1212import io .kafbat .ui .config .ClustersProperties ;
1313import io .kafbat .ui .controller .TopicsController ;
1414import io .kafbat .ui .mapper .ClusterMapper ;
1515import io .kafbat .ui .mapper .ClusterMapperImpl ;
16- import io .kafbat .ui .model .InternalLogDirStats ;
16+ import io .kafbat .ui .model .CleanupPolicy ;
1717import io .kafbat .ui .model .InternalPartition ;
1818import io .kafbat .ui .model .InternalPartitionsOffsets ;
1919import io .kafbat .ui .model .InternalTopic ;
2727import io .kafbat .ui .service .audit .AuditService ;
2828import io .kafbat .ui .service .rbac .AccessControlService ;
2929import io .kafbat .ui .util .AccessControlServiceMock ;
30- import java .util .ArrayList ;
3130import java .util .Comparator ;
3231import java .util .List ;
3332import java .util .Map ;
3736import java .util .function .Function ;
3837import java .util .stream .Collectors ;
3938import java .util .stream .IntStream ;
39+ import org .apache .kafka .clients .admin .ConfigEntry ;
4040import org .apache .kafka .clients .admin .TopicDescription ;
41+ import org .apache .kafka .common .TopicPartition ;
4142import org .apache .kafka .common .TopicPartitionInfo ;
4243import org .junit .jupiter .api .Test ;
43- import org .mockito .ArgumentMatchers ;
4444import org .mockito .Mockito ;
4545import reactor .core .publisher .Mono ;
4646
@@ -70,6 +70,18 @@ class TopicsServicePaginationTest {
7070 private void init (Map <String , InternalTopic > topicsInCache ) {
7171 KafkaCluster kafkaCluster = buildKafkaCluster (LOCAL_KAFKA_CLUSTER_NAME );
7272 statisticsCache .replace (kafkaCluster , Statistics .empty ());
73+
74+ Map <TopicPartition , InternalPartitionsOffsets .Offsets > offsets = topicsInCache .values ().stream ()
75+ .flatMap (t ->
76+ t .getPartitions ().values ().stream ()
77+ .map (p ->
78+ Map .entry (
79+ new TopicPartition (t .getName (), p .getPartition ()),
80+ new InternalPartitionsOffsets .Offsets (p .getOffsetMin (), p .getOffsetMax ())
81+ )
82+ )
83+ ).collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue ));
84+
7385 statisticsCache .update (
7486 kafkaCluster ,
7587 topicsInCache .entrySet ().stream ().collect (
@@ -78,8 +90,11 @@ private void init(Map<String, InternalTopic> topicsInCache) {
7890 v -> toTopicDescription (v .getValue ())
7991 )
8092 ),
81- Map .of (),
82- new InternalPartitionsOffsets (Map .of ()),
93+ topicsInCache .entrySet ().stream ()
94+ .map (t ->
95+ Map .entry (t .getKey (), List .of (new ConfigEntry (CLEANUP_POLICY_CONFIG , "delete" )))
96+ ).collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue )),
97+ new InternalPartitionsOffsets (offsets ),
8398 clustersProperties
8499 );
85100 when (adminClientService .get (isA (KafkaCluster .class ))).thenReturn (Mono .just (reactiveAdminClient ));
@@ -318,4 +333,61 @@ void shouldListTopicsOrderedByPartitionsCount() {
318333 );
319334 }
320335
336+ @ Test
337+ void shouldListTopicsOrderedByMessagesCount () {
338+ Map <String , InternalTopic > internalTopics = IntStream .rangeClosed (1 , 100 ).boxed ()
339+ .map (i -> new TopicDescription (UUID .randomUUID ().toString (), false ,
340+ IntStream .range (0 , i )
341+ .mapToObj (p ->
342+ new TopicPartitionInfo (p , null , List .of (), List .of ()))
343+ .collect (Collectors .toList ())))
344+ .map (topicDescription ->
345+ InternalTopic .from (topicDescription , List .of (),
346+ new InternalPartitionsOffsets (
347+ topicDescription .partitions ().stream ()
348+ .map (p -> Map .entry (
349+ new TopicPartition (topicDescription .name (), p .partition ()),
350+ new InternalPartitionsOffsets .Offsets (0L , (long ) p .partition ())
351+ )).collect (Collectors .toMap (
352+ Map .Entry ::getKey ,
353+ Map .Entry ::getValue
354+ ))
355+ ),
356+ Metrics .empty (), null , null , "_" )
357+ .toBuilder ().cleanUpPolicy (CleanupPolicy .DELETE ).build ()
358+ ).collect (Collectors .toMap (InternalTopic ::getName , Function .identity ()));
359+
360+ init (internalTopics );
361+
362+ var topicsSortedAsc = topicsController
363+ .getTopics (LOCAL_KAFKA_CLUSTER_NAME , null , null , null ,
364+ null , TopicColumnsToSortDTO .MESSAGES_COUNT , null , null ).block ();
365+
366+ assertThat (topicsSortedAsc .getBody ().getPageCount ()).isEqualTo (4 );
367+ assertThat (topicsSortedAsc .getBody ().getTopics ()).hasSize (25 );
368+ assertThat (topicsSortedAsc .getBody ().getTopics ()).containsExactlyElementsOf (
369+ internalTopics .values ().stream ()
370+ .map (clusterMapper ::toTopic )
371+ .sorted (Comparator .comparing (
372+ (t ) -> t .getMessagesCount ().get ()
373+ ))
374+ .limit (25 )
375+ .collect (Collectors .toList ())
376+ );
377+
378+ var topicsSortedDesc = topicsController
379+ .getTopics (LOCAL_KAFKA_CLUSTER_NAME , null , null , null ,
380+ null , TopicColumnsToSortDTO .TOTAL_PARTITIONS , SortOrderDTO .DESC , null ).block ();
381+
382+ assertThat (topicsSortedDesc .getBody ().getPageCount ()).isEqualTo (4 );
383+ assertThat (topicsSortedDesc .getBody ().getTopics ()).hasSize (25 );
384+ assertThat (topicsSortedDesc .getBody ().getTopics ()).containsExactlyElementsOf (
385+ internalTopics .values ().stream ()
386+ .map (clusterMapper ::toTopic )
387+ .sorted (Comparator .comparing (TopicDTO ::getPartitionCount ).reversed ())
388+ .limit (25 )
389+ .collect (Collectors .toList ())
390+ );
391+ }
392+
321393}
0 commit comments