Jelajahi Sumber

Feature refactoring, structure simplifying (#250)

German Osin 4 tahun lalu
induk
melakukan
909e196011
69 mengubah file dengan 578 tambahan dan 447 penghapusan
  1. 15 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/client/KafkaConnectClients.java
  2. 5 5
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/client/RetryingKafkaConnectClient.java
  3. 0 15
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/client/KafkaConnectClients.java
  4. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/ClustersProperties.java
  5. 2 2
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/Config.java
  6. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CorsGlobalConfiguration.java
  7. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CustomWebFilter.java
  8. 4 4
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/ReadOnlyModeFilter.java
  9. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/SecurityConfig.java
  10. 32 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/BrokersController.java
  11. 40 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/ClustersController.java
  12. 35 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/ConsumerGroupsController.java
  13. 4 4
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/KafkaConnectController.java
  14. 63 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/MessagesController.java
  15. 106 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/SchemasController.java
  16. 71 0
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/TopicsController.java
  17. 3 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/DeserializationService.java
  18. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/ProtobufFileRecordDeserializer.java
  19. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/RecordDeserializer.java
  20. 2 2
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java
  21. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SimpleRecordDeserializer.java
  22. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/CustomBaseException.java
  23. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/DuplicateEntityException.java
  24. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/GlobalErrorAttributes.java
  25. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/GlobalErrorWebExceptionHandler.java
  26. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/NotFoundException.java
  27. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/ReadOnlyException.java
  28. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/RebalanceInProgressException.java
  29. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/UnprocessableEntityException.java
  30. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/ValidationException.java
  31. 4 5
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/ClusterMapper.java
  32. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/KafkaConnectMapper.java
  33. 1 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/ConsumerPosition.java
  34. 2 2
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/ExtendedAdminClient.java
  35. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalBrokerDiskUsage.java
  36. 1 2
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalBrokerMetrics.java
  37. 1 2
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalClusterMetrics.java
  38. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalPartition.java
  39. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalReplica.java
  40. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalSegmentSizeDto.java
  41. 1 2
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalTopic.java
  42. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalTopicConfig.java
  43. 1 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/KafkaCluster.java
  44. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/KafkaConnectCluster.java
  45. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/InternalCompatibilityCheck.java
  46. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/InternalCompatibilityLevel.java
  47. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/InternalNewSchema.java
  48. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/SubjectIdResponse.java
  49. 0 219
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/rest/MetricsRestController.java
  50. 8 10
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClusterService.java
  51. 1 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClustersMetricsScheduler.java
  52. 4 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClustersStorage.java
  53. 6 7
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ConsumingService.java
  54. 8 10
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/KafkaConnectService.java
  55. 6 7
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/KafkaService.java
  56. 2 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/MetricsUpdateService.java
  57. 10 11
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/SchemaRegistryService.java
  58. 2 3
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ZookeeperService.java
  59. 3 4
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/ClusterUtil.java
  60. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxClusterUtil.java
  61. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxMetricsName.java
  62. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxMetricsValueName.java
  63. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxPoolFactory.java
  64. 1 1
      kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/KafkaConstants.java
  65. 9 4
      kafka-ui-api/src/test/java/com/provectus/kafka/ui/SchemaRegistryServiceTests.java
  66. 2 2
      kafka-ui-api/src/test/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializerTest.java
  67. 15 15
      kafka-ui-contract/src/main/resources/swagger/kafka-connect-api.yaml
  68. 39 39
      kafka-ui-contract/src/main/resources/swagger/kafka-ui-api.yaml
  69. 38 21
      kafka-ui-react-app/src/redux/actions/thunks.ts

+ 15 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/client/KafkaConnectClients.java

@@ -0,0 +1,15 @@
+package com.provectus.kafka.ui.client;
+
+import com.provectus.kafka.ui.connect.api.KafkaConnectClientApi;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class KafkaConnectClients {
+
+    private static final Map<String, KafkaConnectClientApi> CACHE = new ConcurrentHashMap<>();
+
+    public static KafkaConnectClientApi withBaseUrl(String basePath) {
+        return CACHE.computeIfAbsent(basePath, RetryingKafkaConnectClient::new);
+    }
+}

+ 5 - 5
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/client/RetryingKafkaConnectClient.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/client/RetryingKafkaConnectClient.java

@@ -1,9 +1,9 @@
-package com.provectus.kafka.ui.cluster.client;
+package com.provectus.kafka.ui.client;
 
 
-import com.provectus.kafka.ui.cluster.exception.RebalanceInProgressException;
-import com.provectus.kafka.ui.cluster.exception.ValidationException;
+import com.provectus.kafka.ui.exception.RebalanceInProgressException;
+import com.provectus.kafka.ui.exception.ValidationException;
 import com.provectus.kafka.ui.connect.ApiClient;
 import com.provectus.kafka.ui.connect.ApiClient;
-import com.provectus.kafka.ui.connect.api.ConnectApi;
+import com.provectus.kafka.ui.connect.api.KafkaConnectClientApi;
 import com.provectus.kafka.ui.connect.model.Connector;
 import com.provectus.kafka.ui.connect.model.Connector;
 import com.provectus.kafka.ui.connect.model.NewConnector;
 import com.provectus.kafka.ui.connect.model.NewConnector;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;
@@ -22,7 +22,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
 @Log4j2
 @Log4j2
-public class RetryingKafkaConnectClient extends ConnectApi {
+public class RetryingKafkaConnectClient extends KafkaConnectClientApi {
     private static final int MAX_RETRIES = 5;
     private static final int MAX_RETRIES = 5;
 
 
     public RetryingKafkaConnectClient(String basePath) {
     public RetryingKafkaConnectClient(String basePath) {

+ 0 - 15
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/client/KafkaConnectClients.java

@@ -1,15 +0,0 @@
-package com.provectus.kafka.ui.cluster.client;
-
-import com.provectus.kafka.ui.connect.api.ConnectApi;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-public final class KafkaConnectClients {
-
-    private static final Map<String, ConnectApi> CACHE = new ConcurrentHashMap<>();
-
-    public static ConnectApi withBaseUrl(String basePath) {
-        return CACHE.computeIfAbsent(basePath, RetryingKafkaConnectClient::new);
-    }
-}

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/config/ClustersProperties.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/ClustersProperties.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.config;
+package com.provectus.kafka.ui.config;
 
 
 import java.util.Properties;
 import java.util.Properties;
 import lombok.Data;
 import lombok.Data;

+ 2 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/config/Config.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/Config.java

@@ -1,6 +1,6 @@
-package com.provectus.kafka.ui.cluster.config;
+package com.provectus.kafka.ui.config;
 
 
-import com.provectus.kafka.ui.cluster.util.JmxPoolFactory;
+import com.provectus.kafka.ui.util.JmxPoolFactory;
 import org.apache.commons.pool2.KeyedObjectPool;
 import org.apache.commons.pool2.KeyedObjectPool;
 import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
 import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
 import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
 import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/rest/config/CorsGlobalConfiguration.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CorsGlobalConfiguration.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.rest.config;
+package com.provectus.kafka.ui.config;
 
 
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Profile;
 import org.springframework.context.annotation.Profile;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/rest/config/CustomWebFilter.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CustomWebFilter.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.rest.config;
+package com.provectus.kafka.ui.config;
 
 
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 import org.springframework.web.server.ServerWebExchange;
 import org.springframework.web.server.ServerWebExchange;

+ 4 - 4
kafka-ui-api/src/main/java/com/provectus/kafka/ui/rest/config/ReadOnlyModeFilter.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/ReadOnlyModeFilter.java

@@ -1,8 +1,8 @@
-package com.provectus.kafka.ui.rest.config;
+package com.provectus.kafka.ui.config;
 
 
-import com.provectus.kafka.ui.cluster.exception.NotFoundException;
-import com.provectus.kafka.ui.cluster.exception.ReadOnlyException;
-import com.provectus.kafka.ui.cluster.model.ClustersStorage;
+import com.provectus.kafka.ui.exception.NotFoundException;
+import com.provectus.kafka.ui.exception.ReadOnlyException;
+import com.provectus.kafka.ui.service.ClustersStorage;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.core.annotation.Order;
 import org.springframework.core.annotation.Order;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/config/SecurityConfig.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/SecurityConfig.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.config;
+package com.provectus.kafka.ui.config;
 
 
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;

+ 32 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/BrokersController.java

@@ -0,0 +1,32 @@
+package com.provectus.kafka.ui.controller;
+
+import com.provectus.kafka.ui.api.BrokersApi;
+import com.provectus.kafka.ui.service.ClusterService;
+import com.provectus.kafka.ui.model.Broker;
+import com.provectus.kafka.ui.model.BrokerMetrics;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequiredArgsConstructor
+@Log4j2
+public class BrokersController implements BrokersApi {
+  private final ClusterService clusterService;
+
+  @Override
+  public Mono<ResponseEntity<BrokerMetrics>> getBrokersMetrics(String clusterName, Integer id, ServerWebExchange exchange) {
+    return clusterService.getBrokerMetrics(clusterName, id)
+        .map(ResponseEntity::ok)
+        .onErrorReturn(ResponseEntity.notFound().build());
+  }
+
+  @Override
+  public Mono<ResponseEntity<Flux<Broker>>> getBrokers(String clusterName, ServerWebExchange exchange) {
+    return Mono.just(ResponseEntity.ok(clusterService.getBrokers(clusterName)));
+  }
+}

+ 40 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/ClustersController.java

@@ -0,0 +1,40 @@
+package com.provectus.kafka.ui.controller;
+
+import com.provectus.kafka.ui.api.ClustersApi;
+import com.provectus.kafka.ui.service.ClusterService;
+import com.provectus.kafka.ui.model.Cluster;
+import com.provectus.kafka.ui.model.ClusterMetrics;
+import com.provectus.kafka.ui.model.ClusterStats;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequiredArgsConstructor
+@Log4j2
+public class ClustersController implements ClustersApi {
+  private final ClusterService clusterService;
+
+  @Override
+  public Mono<ResponseEntity<ClusterMetrics>> getClusterMetrics(String clusterName, ServerWebExchange exchange) {
+    return clusterService.getClusterMetrics(clusterName)
+        .map(ResponseEntity::ok)
+        .onErrorReturn(ResponseEntity.notFound().build());
+  }
+
+  @Override
+  public Mono<ResponseEntity<ClusterStats>> getClusterStats(String clusterName, ServerWebExchange exchange) {
+    return clusterService.getClusterStats(clusterName)
+        .map(ResponseEntity::ok)
+        .onErrorReturn(ResponseEntity.notFound().build());
+  }
+
+  @Override
+  public Mono<ResponseEntity<Flux<Cluster>>> getClusters(ServerWebExchange exchange) {
+    return Mono.just(ResponseEntity.ok(Flux.fromIterable(clusterService.getClusters())));
+  }
+}

+ 35 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/ConsumerGroupsController.java

@@ -0,0 +1,35 @@
+package com.provectus.kafka.ui.controller;
+
+import com.provectus.kafka.ui.api.ConsumerGroupsApi;
+import com.provectus.kafka.ui.service.ClusterService;
+import com.provectus.kafka.ui.model.ConsumerGroup;
+import com.provectus.kafka.ui.model.ConsumerGroupDetails;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequiredArgsConstructor
+@Log4j2
+public class ConsumerGroupsController implements ConsumerGroupsApi {
+  private final ClusterService clusterService;
+
+  @Override
+  public Mono<ResponseEntity<ConsumerGroupDetails>> getConsumerGroup(
+      String clusterName, String consumerGroupId, ServerWebExchange exchange) {
+    return clusterService.getConsumerGroupDetail(clusterName, consumerGroupId).map(ResponseEntity::ok);
+  }
+
+
+  @Override
+  public Mono<ResponseEntity<Flux<ConsumerGroup>>> getConsumerGroups(String clusterName, ServerWebExchange exchange) {
+    return clusterService.getConsumerGroups(clusterName)
+        .map(Flux::fromIterable)
+        .map(ResponseEntity::ok)
+        .switchIfEmpty(Mono.just(ResponseEntity.notFound().build())); // TODO: check behaviour on cluster not found and empty groups list
+  }
+}

+ 4 - 4
kafka-ui-api/src/main/java/com/provectus/kafka/ui/rest/KafkaConnectRestController.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/KafkaConnectController.java

@@ -1,7 +1,7 @@
-package com.provectus.kafka.ui.rest;
+package com.provectus.kafka.ui.controller;
 
 
-import com.provectus.kafka.ui.api.ApiClustersConnectsApi;
-import com.provectus.kafka.ui.cluster.service.KafkaConnectService;
+import com.provectus.kafka.ui.api.KafkaConnectApi;
+import com.provectus.kafka.ui.service.KafkaConnectService;
 import com.provectus.kafka.ui.model.*;
 import com.provectus.kafka.ui.model.*;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;
@@ -17,7 +17,7 @@ import java.util.Map;
 @RestController
 @RestController
 @RequiredArgsConstructor
 @RequiredArgsConstructor
 @Log4j2
 @Log4j2
-public class KafkaConnectRestController implements ApiClustersConnectsApi {
+public class KafkaConnectController implements KafkaConnectApi {
     private final KafkaConnectService kafkaConnectService;
     private final KafkaConnectService kafkaConnectService;
 
 
     @Override
     @Override

+ 63 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/MessagesController.java

@@ -0,0 +1,63 @@
+package com.provectus.kafka.ui.controller;
+
+import com.provectus.kafka.ui.api.MessagesApi;
+import com.provectus.kafka.ui.model.ConsumerPosition;
+import com.provectus.kafka.ui.service.ClusterService;
+import com.provectus.kafka.ui.model.SeekType;
+import com.provectus.kafka.ui.model.TopicMessage;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import javax.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequiredArgsConstructor
+@Log4j2
+public class MessagesController implements MessagesApi {
+  private final ClusterService clusterService;
+
+  @Override
+  public Mono<ResponseEntity<Void>> deleteTopicMessages(
+      String clusterName, String topicName, @Valid List<Integer> partitions, ServerWebExchange exchange) {
+    return clusterService.deleteTopicMessages(
+        clusterName,
+        topicName,
+        Optional.ofNullable(partitions).orElse(List.of())
+    ).map(ResponseEntity::ok);
+  }
+
+
+  @Override
+  public Mono<ResponseEntity<Flux<TopicMessage>>> getTopicMessages(
+      String clusterName, String topicName, @Valid SeekType seekType, @Valid List<String> seekTo,
+      @Valid Integer limit, @Valid String q, ServerWebExchange exchange) {
+    return parseConsumerPosition(seekType, seekTo)
+        .map(consumerPosition -> ResponseEntity.ok(clusterService.getMessages(clusterName, topicName, consumerPosition, q, limit)));
+  }
+
+  private Mono<ConsumerPosition> parseConsumerPosition(SeekType seekType, List<String> seekTo) {
+    return Mono.justOrEmpty(seekTo)
+        .defaultIfEmpty(Collections.emptyList())
+        .flatMapIterable(Function.identity())
+        .map(p -> {
+          String[] splited = p.split("::");
+          if (splited.length != 2) {
+            throw new IllegalArgumentException("Wrong seekTo argument format. See API docs for details");
+          }
+
+          return Pair.of(Integer.parseInt(splited[0]), Long.parseLong(splited[1]));
+        })
+        .collectMap(Pair::getKey, Pair::getValue)
+        .map(positions -> new ConsumerPosition(seekType != null ? seekType : SeekType.BEGINNING, positions));
+  }
+
+}

+ 106 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/SchemasController.java

@@ -0,0 +1,106 @@
+package com.provectus.kafka.ui.controller;
+
+import com.provectus.kafka.ui.api.SchemasApi;
+import com.provectus.kafka.ui.service.SchemaRegistryService;
+import com.provectus.kafka.ui.model.CompatibilityCheckResponse;
+import com.provectus.kafka.ui.model.CompatibilityLevel;
+import com.provectus.kafka.ui.model.NewSchemaSubject;
+import com.provectus.kafka.ui.model.SchemaSubject;
+import javax.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequiredArgsConstructor
+@Log4j2
+public class SchemasController implements SchemasApi {
+
+  private final SchemaRegistryService schemaRegistryService;
+
+  @Override
+  public Mono<ResponseEntity<CompatibilityCheckResponse>> checkSchemaCompatibility(
+      String clusterName, String subject, @Valid Mono<NewSchemaSubject> newSchemaSubject, ServerWebExchange exchange) {
+    return schemaRegistryService.checksSchemaCompatibility(clusterName, subject, newSchemaSubject)
+        .map(ResponseEntity::ok);
+  }
+
+  @Override
+  public Mono<ResponseEntity<SchemaSubject>> createNewSchema(String clusterName,
+                                                             @Valid Mono<NewSchemaSubject> newSchemaSubject,
+                                                             ServerWebExchange exchange) {
+    return schemaRegistryService
+        .registerNewSchema(clusterName, newSchemaSubject)
+        .map(ResponseEntity::ok);
+  }
+
+  @Override
+  public Mono<ResponseEntity<Void>> deleteLatestSchema(
+      String clusterName, String subject, ServerWebExchange exchange) {
+    return schemaRegistryService.deleteLatestSchemaSubject(clusterName, subject);
+  }
+
+  @Override
+  public Mono<ResponseEntity<Void>> deleteSchema(
+      String clusterName, String subjectName, ServerWebExchange exchange) {
+    return schemaRegistryService.deleteSchemaSubjectEntirely(clusterName, subjectName);
+  }
+
+  @Override
+  public Mono<ResponseEntity<Void>> deleteSchemaByVersion(
+      String clusterName, String subjectName, Integer version, ServerWebExchange exchange) {
+    return schemaRegistryService.deleteSchemaSubjectByVersion(clusterName, subjectName, version);
+  }
+
+  @Override
+  public Mono<ResponseEntity<Flux<SchemaSubject>>> getAllVersionsBySubject(
+      String clusterName, String subjectName, ServerWebExchange exchange) {
+    Flux<SchemaSubject> schemas = schemaRegistryService.getAllVersionsBySubject(clusterName, subjectName);
+    return Mono.just(ResponseEntity.ok(schemas));
+  }
+
+  @Override
+  public Mono<ResponseEntity<CompatibilityLevel>> getGlobalSchemaCompatibilityLevel(
+      String clusterName, ServerWebExchange exchange) {
+    return schemaRegistryService.getGlobalSchemaCompatibilityLevel(clusterName)
+        .map(ResponseEntity::ok)
+        .defaultIfEmpty(ResponseEntity.notFound().build());
+  }
+
+  @Override
+  public Mono<ResponseEntity<SchemaSubject>> getLatestSchema(String clusterName, String subject, ServerWebExchange exchange) {
+    return schemaRegistryService.getLatestSchemaVersionBySubject(clusterName, subject).map(ResponseEntity::ok);
+  }
+
+  @Override
+  public Mono<ResponseEntity<SchemaSubject>> getSchemaByVersion(
+      String clusterName, String subject, Integer version, ServerWebExchange exchange) {
+    return schemaRegistryService.getSchemaSubjectByVersion(clusterName, subject, version).map(ResponseEntity::ok);
+  }
+
+  @Override
+  public Mono<ResponseEntity<Flux<SchemaSubject>>> getSchemas(String clusterName, ServerWebExchange exchange) {
+    Flux<SchemaSubject> subjects = schemaRegistryService.getAllLatestVersionSchemas(clusterName);
+    return Mono.just(ResponseEntity.ok(subjects));
+  }
+
+  @Override
+  public Mono<ResponseEntity<Void>> updateGlobalSchemaCompatibilityLevel(
+      String clusterName, @Valid Mono<CompatibilityLevel> compatibilityLevel, ServerWebExchange exchange) {
+    log.info("Updating schema compatibility globally");
+    return schemaRegistryService.updateSchemaCompatibility(clusterName, compatibilityLevel)
+        .map(ResponseEntity::ok);
+  }
+
+  @Override
+  public Mono<ResponseEntity<Void>> updateSchemaCompatibilityLevel(
+      String clusterName, String subject, @Valid Mono<CompatibilityLevel> compatibilityLevel, ServerWebExchange exchange) {
+    log.info("Updating schema compatibility for subject: {}", subject);
+    return schemaRegistryService.updateSchemaCompatibility(clusterName, subject, compatibilityLevel)
+        .map(ResponseEntity::ok);
+  }
+}

+ 71 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/TopicsController.java

@@ -0,0 +1,71 @@
+package com.provectus.kafka.ui.controller;
+
+import com.provectus.kafka.ui.api.TopicsApi;
+import com.provectus.kafka.ui.service.ClusterService;
+import com.provectus.kafka.ui.model.Topic;
+import com.provectus.kafka.ui.model.TopicConfig;
+import com.provectus.kafka.ui.model.TopicDetails;
+import com.provectus.kafka.ui.model.TopicFormData;
+import javax.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequiredArgsConstructor
+@Log4j2
+public class TopicsController implements TopicsApi {
+  private final ClusterService clusterService;
+
+  @Override
+  public Mono<ResponseEntity<Topic>> createTopic(
+      String clusterName, @Valid Mono<TopicFormData> topicFormData, ServerWebExchange exchange) {
+    return clusterService.createTopic(clusterName, topicFormData)
+        .map(s -> new ResponseEntity<>(s, HttpStatus.OK))
+        .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
+  }
+
+  @Override
+  public Mono<ResponseEntity<Void>> deleteTopic(
+      String clusterName, String topicName, ServerWebExchange exchange) {
+    return clusterService.deleteTopic(clusterName, topicName).map(ResponseEntity::ok);
+  }
+
+
+  @Override
+  public Mono<ResponseEntity<Flux<TopicConfig>>> getTopicConfigs(
+      String clusterName, String topicName, ServerWebExchange exchange) {
+    return Mono.just(
+        clusterService.getTopicConfigs(clusterName, topicName)
+            .map(Flux::fromIterable)
+            .map(ResponseEntity::ok)
+            .orElse(ResponseEntity.notFound().build())
+    );
+  }
+
+  @Override
+  public Mono<ResponseEntity<TopicDetails>> getTopicDetails(
+      String clusterName, String topicName, ServerWebExchange exchange) {
+    return Mono.just(
+        clusterService.getTopicDetails(clusterName, topicName)
+            .map(ResponseEntity::ok)
+            .orElse(ResponseEntity.notFound().build())
+    );
+  }
+
+  @Override
+  public Mono<ResponseEntity<Flux<Topic>>> getTopics(String clusterName, ServerWebExchange exchange) {
+    return Mono.just(ResponseEntity.ok(Flux.fromIterable(clusterService.getTopics(clusterName))));
+  }
+
+  @Override
+  public Mono<ResponseEntity<Topic>> updateTopic(
+      String clusterId, String topicName, @Valid Mono<TopicFormData> topicFormData, ServerWebExchange exchange) {
+    return clusterService.updateTopic(clusterId, topicName, topicFormData).map(ResponseEntity::ok);
+  }
+}

+ 3 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/deserialization/DeserializationService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/DeserializationService.java

@@ -1,8 +1,8 @@
-package com.provectus.kafka.ui.cluster.deserialization;
+package com.provectus.kafka.ui.deserialization;
 
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.provectus.kafka.ui.cluster.model.ClustersStorage;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
+import com.provectus.kafka.ui.service.ClustersStorage;
+import com.provectus.kafka.ui.model.KafkaCluster;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/deserialization/ProtobufFileRecordDeserializer.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/ProtobufFileRecordDeserializer.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.deserialization;
+package com.provectus.kafka.ui.deserialization;
 
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/deserialization/RecordDeserializer.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/RecordDeserializer.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.deserialization;
+package com.provectus.kafka.ui.deserialization;
 
 
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.common.utils.Bytes;
 import org.apache.kafka.common.utils.Bytes;

+ 2 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/deserialization/SchemaRegistryRecordDeserializer.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java

@@ -1,9 +1,9 @@
-package com.provectus.kafka.ui.cluster.deserialization;
+package com.provectus.kafka.ui.deserialization;
 
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.protobuf.Message;
 import com.google.protobuf.Message;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
+import com.provectus.kafka.ui.model.KafkaCluster;
 import io.confluent.kafka.schemaregistry.SchemaProvider;
 import io.confluent.kafka.schemaregistry.SchemaProvider;
 import io.confluent.kafka.schemaregistry.avro.AvroSchemaProvider;
 import io.confluent.kafka.schemaregistry.avro.AvroSchemaProvider;
 import io.confluent.kafka.schemaregistry.avro.AvroSchemaUtils;
 import io.confluent.kafka.schemaregistry.avro.AvroSchemaUtils;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/deserialization/SimpleRecordDeserializer.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SimpleRecordDeserializer.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.deserialization;
+package com.provectus.kafka.ui.deserialization;
 
 
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringDeserializer;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/CustomBaseException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/CustomBaseException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/DuplicateEntityException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/DuplicateEntityException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/GlobalErrorAttributes.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/GlobalErrorAttributes.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
 import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/GlobalErrorWebExceptionHandler.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/GlobalErrorWebExceptionHandler.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.boot.autoconfigure.web.ResourceProperties;
 import org.springframework.boot.autoconfigure.web.ResourceProperties;
 import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
 import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/NotFoundException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/NotFoundException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/ReadOnlyException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/ReadOnlyException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/RebalanceInProgressException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/RebalanceInProgressException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/UnprocessableEntityException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/UnprocessableEntityException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/exception/ValidationException.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/ValidationException.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.exception;
+package com.provectus.kafka.ui.exception;
 
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 
 

+ 4 - 5
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/mapper/ClusterMapper.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/ClusterMapper.java

@@ -1,10 +1,9 @@
-package com.provectus.kafka.ui.cluster.mapper;
+package com.provectus.kafka.ui.mapper;
 
 
-import com.provectus.kafka.ui.cluster.config.ClustersProperties;
-import com.provectus.kafka.ui.cluster.model.*;
-import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibilityCheck;
-import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibilityLevel;
+import com.provectus.kafka.ui.config.ClustersProperties;
 import com.provectus.kafka.ui.model.*;
 import com.provectus.kafka.ui.model.*;
+import com.provectus.kafka.ui.model.schemaregistry.InternalCompatibilityCheck;
+import com.provectus.kafka.ui.model.schemaregistry.InternalCompatibilityLevel;
 import java.util.Properties;
 import java.util.Properties;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Mapping;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/mapper/KafkaConnectMapper.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/KafkaConnectMapper.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.mapper;
+package com.provectus.kafka.ui.mapper;
 
 
 import com.provectus.kafka.ui.connect.model.ConnectorStatusConnector;
 import com.provectus.kafka.ui.connect.model.ConnectorStatusConnector;
 import com.provectus.kafka.ui.connect.model.ConnectorTask;
 import com.provectus.kafka.ui.connect.model.ConnectorTask;

+ 1 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/ConsumerPosition.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/ConsumerPosition.java

@@ -1,11 +1,9 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Value;
 import lombok.Value;
 
 
 import java.util.Map;
 import java.util.Map;
 
 
-import com.provectus.kafka.ui.model.SeekType;
-
 @Value
 @Value
 public class ConsumerPosition {
 public class ConsumerPosition {
 
 

+ 2 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/ExtendedAdminClient.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/ExtendedAdminClient.java

@@ -1,6 +1,6 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
-import com.provectus.kafka.ui.cluster.util.ClusterUtil;
+import com.provectus.kafka.ui.util.ClusterUtil;
 import lombok.Data;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.apache.kafka.clients.admin.AdminClient;
 import org.apache.kafka.clients.admin.AdminClient;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalBrokerDiskUsage.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalBrokerDiskUsage.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;

+ 1 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalBrokerMetrics.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalBrokerMetrics.java

@@ -1,6 +1,5 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
-import com.provectus.kafka.ui.model.Metric;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
 
 

+ 1 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalClusterMetrics.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalClusterMetrics.java

@@ -1,6 +1,5 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
-import com.provectus.kafka.ui.model.Metric;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalPartition.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalPartition.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalReplica.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalReplica.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalSegmentSizeDto.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalSegmentSizeDto.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;

+ 1 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalTopic.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalTopic.java

@@ -1,8 +1,7 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
-import org.apache.kafka.common.TopicPartition;
 
 
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/InternalTopicConfig.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalTopicConfig.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 
 
 import lombok.Builder;
 import lombok.Builder;

+ 1 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/KafkaCluster.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/KafkaCluster.java

@@ -1,6 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
-
-import com.provectus.kafka.ui.model.ServerStatus;
+package com.provectus.kafka.ui.model;
 
 
 import java.util.List;
 import java.util.List;
 import java.util.Properties;
 import java.util.Properties;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/KafkaConnectCluster.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/KafkaConnectCluster.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.model;
 
 
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/schemaregistry/InternalCompatibilityCheck.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/InternalCompatibilityCheck.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model.schemaregistry;
+package com.provectus.kafka.ui.model.schemaregistry;
 
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
 import lombok.Data;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/schemaregistry/InternalCompatibilityLevel.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/InternalCompatibilityLevel.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model.schemaregistry;
+package com.provectus.kafka.ui.model.schemaregistry;
 
 
 import lombok.Data;
 import lombok.Data;
 
 

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/schemaregistry/InternalNewSchema.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/InternalNewSchema.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model.schemaregistry;
+package com.provectus.kafka.ui.model.schemaregistry;
 
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.provectus.kafka.ui.model.SchemaType;
 import com.provectus.kafka.ui.model.SchemaType;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/schemaregistry/SubjectIdResponse.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/schemaregistry/SubjectIdResponse.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.model.schemaregistry;
+package com.provectus.kafka.ui.model.schemaregistry;
 
 
 import lombok.Data;
 import lombok.Data;
 
 

+ 0 - 219
kafka-ui-api/src/main/java/com/provectus/kafka/ui/rest/MetricsRestController.java

@@ -1,219 +0,0 @@
-package com.provectus.kafka.ui.rest;
-
-import com.provectus.kafka.ui.api.ApiClustersApi;
-import com.provectus.kafka.ui.cluster.model.ConsumerPosition;
-import com.provectus.kafka.ui.cluster.service.ClusterService;
-import com.provectus.kafka.ui.cluster.service.SchemaRegistryService;
-import com.provectus.kafka.ui.model.*;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.tuple.Pair;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import javax.validation.Valid;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-
-@RestController
-@RequiredArgsConstructor
-@Log4j2
-public class MetricsRestController implements ApiClustersApi {
-
-    private final ClusterService clusterService;
-    private final SchemaRegistryService schemaRegistryService;
-
-    @Override
-    public Mono<ResponseEntity<Flux<Cluster>>> getClusters(ServerWebExchange exchange) {
-        return Mono.just(ResponseEntity.ok(Flux.fromIterable(clusterService.getClusters())));
-    }
-
-    @Override
-    public Mono<ResponseEntity<BrokerMetrics>> getBrokersMetrics(String clusterName, Integer id, ServerWebExchange exchange) {
-        return clusterService.getBrokerMetrics(clusterName, id)
-                .map(ResponseEntity::ok)
-                .onErrorReturn(ResponseEntity.notFound().build());
-    }
-
-    @Override
-    public Mono<ResponseEntity<ClusterMetrics>> getClusterMetrics(String clusterName, ServerWebExchange exchange) {
-        return clusterService.getClusterMetrics(clusterName)
-                .map(ResponseEntity::ok)
-                .onErrorReturn(ResponseEntity.notFound().build());
-    }
-
-    @Override
-    public Mono<ResponseEntity<ClusterStats>> getClusterStats(String clusterName, ServerWebExchange exchange) {
-        return clusterService.getClusterStats(clusterName)
-                .map(ResponseEntity::ok)
-                .onErrorReturn(ResponseEntity.notFound().build());
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<Topic>>> getTopics(String clusterName, ServerWebExchange exchange) {
-        return Mono.just(ResponseEntity.ok(Flux.fromIterable(clusterService.getTopics(clusterName))));
-    }
-
-    @Override
-    public Mono<ResponseEntity<TopicDetails>> getTopicDetails(String clusterName, String topicName, ServerWebExchange exchange) {
-        return Mono.just(
-                clusterService.getTopicDetails(clusterName, topicName)
-                        .map(ResponseEntity::ok)
-                        .orElse(ResponseEntity.notFound().build())
-        );
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<TopicConfig>>> getTopicConfigs(String clusterName, String topicName, ServerWebExchange exchange) {
-        return Mono.just(
-                clusterService.getTopicConfigs(clusterName, topicName)
-                        .map(Flux::fromIterable)
-                        .map(ResponseEntity::ok)
-                        .orElse(ResponseEntity.notFound().build())
-        );
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<TopicMessage>>> getTopicMessages(String clusterName, String topicName, @Valid SeekType seekType, @Valid List<String> seekTo, @Valid Integer limit, @Valid String q, ServerWebExchange exchange) {
-        return parseConsumerPosition(seekType, seekTo)
-                .map(consumerPosition -> ResponseEntity.ok(clusterService.getMessages(clusterName, topicName, consumerPosition, q, limit)));
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> deleteTopicMessages(String clusterName, String topicName, @Valid List<Integer> partitions, ServerWebExchange exchange) {
-        return clusterService.deleteTopicMessages(clusterName, topicName, Optional.ofNullable(partitions).orElse(List.of()))
-                .map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Topic>> createTopic(String clusterName, @Valid Mono<TopicFormData> topicFormData, ServerWebExchange exchange) {
-        return clusterService.createTopic(clusterName, topicFormData)
-                .map(s -> new ResponseEntity<>(s, HttpStatus.OK))
-                .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<Broker>>> getBrokers(String clusterName, ServerWebExchange exchange) {
-        return Mono.just(ResponseEntity.ok(clusterService.getBrokers(clusterName)));
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<ConsumerGroup>>> getConsumerGroups(String clusterName, ServerWebExchange exchange) {
-        return clusterService.getConsumerGroups(clusterName)
-                .map(Flux::fromIterable)
-                .map(ResponseEntity::ok)
-                .switchIfEmpty(Mono.just(ResponseEntity.notFound().build())); // TODO: check behaviour on cluster not found and empty groups list
-    }
-
-    @Override
-    public Mono<ResponseEntity<SchemaSubject>> getLatestSchema(String clusterName, String subject, ServerWebExchange exchange) {
-        return schemaRegistryService.getLatestSchemaVersionBySubject(clusterName, subject).map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<SchemaSubject>> getSchemaByVersion(String clusterName, String subject, Integer version, ServerWebExchange exchange) {
-        return schemaRegistryService.getSchemaSubjectByVersion(clusterName, subject, version).map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<SchemaSubject>>> getSchemas(String clusterName, ServerWebExchange exchange) {
-        Flux<SchemaSubject> subjects = schemaRegistryService.getAllLatestVersionSchemas(clusterName);
-        return Mono.just(ResponseEntity.ok(subjects));
-    }
-
-    @Override
-    public Mono<ResponseEntity<Flux<SchemaSubject>>> getAllVersionsBySubject(String clusterName, String subjectName, ServerWebExchange exchange) {
-        Flux<SchemaSubject> schemas = schemaRegistryService.getAllVersionsBySubject(clusterName, subjectName);
-        return Mono.just(ResponseEntity.ok(schemas));
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> deleteLatestSchema(String clusterName, String subject, ServerWebExchange exchange) {
-        return schemaRegistryService.deleteLatestSchemaSubject(clusterName, subject);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> deleteSchemaByVersion(String clusterName, String subjectName, Integer version, ServerWebExchange exchange) {
-        return schemaRegistryService.deleteSchemaSubjectByVersion(clusterName, subjectName, version);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> deleteSchema(String clusterName, String subjectName, ServerWebExchange exchange) {
-        return schemaRegistryService.deleteSchemaSubjectEntirely(clusterName, subjectName);
-    }
-
-    @Override
-    public Mono<ResponseEntity<SchemaSubject>> createNewSchema(String clusterName,
-                                                               @Valid Mono<NewSchemaSubject> newSchemaSubject,
-                                                               ServerWebExchange exchange) {
-        return schemaRegistryService
-                .registerNewSchema(clusterName, newSchemaSubject)
-                .map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<ConsumerGroupDetails>> getConsumerGroup(String clusterName, String consumerGroupId, ServerWebExchange exchange) {
-        return clusterService.getConsumerGroupDetail(clusterName, consumerGroupId).map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Topic>> updateTopic(String clusterId, String topicName, @Valid Mono<TopicFormData> topicFormData, ServerWebExchange exchange) {
-        return clusterService.updateTopic(clusterId, topicName, topicFormData).map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> deleteTopic(String clusterName, String topicName, ServerWebExchange exchange) {
-        return clusterService.deleteTopic(clusterName, topicName).map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<CompatibilityLevel>> getGlobalSchemaCompatibilityLevel(String clusterName, ServerWebExchange exchange) {
-        return schemaRegistryService.getGlobalSchemaCompatibilityLevel(clusterName)
-                .map(ResponseEntity::ok)
-                .defaultIfEmpty(ResponseEntity.notFound().build());
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> updateGlobalSchemaCompatibilityLevel(String clusterName, @Valid Mono<CompatibilityLevel> compatibilityLevel, ServerWebExchange exchange) {
-        log.info("Updating schema compatibility globally");
-        return schemaRegistryService.updateSchemaCompatibility(clusterName, compatibilityLevel)
-                .map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<CompatibilityCheckResponse>> checkSchemaCompatibility(String clusterName, String subject,
-                                                                                     @Valid Mono<NewSchemaSubject> newSchemaSubject,
-                                                                                     ServerWebExchange exchange) {
-        return schemaRegistryService.checksSchemaCompatibility(clusterName, subject, newSchemaSubject)
-                .map(ResponseEntity::ok);
-    }
-
-    @Override
-    public Mono<ResponseEntity<Void>> updateSchemaCompatibilityLevel(String clusterName, String subject, @Valid Mono<CompatibilityLevel> compatibilityLevel, ServerWebExchange exchange) {
-        log.info("Updating schema compatibility for subject: {}", subject);
-        return schemaRegistryService.updateSchemaCompatibility(clusterName, subject, compatibilityLevel)
-                .map(ResponseEntity::ok);
-    }
-
-    private Mono<ConsumerPosition> parseConsumerPosition(SeekType seekType, List<String> seekTo) {
-        return Mono.justOrEmpty(seekTo)
-                .defaultIfEmpty(Collections.emptyList())
-                .flatMapIterable(Function.identity())
-                .map(p -> {
-                    String[] splited = p.split("::");
-                    if (splited.length != 2) {
-                        throw new IllegalArgumentException("Wrong seekTo argument format. See API docs for details");
-                    }
-
-                    return Pair.of(Integer.parseInt(splited[0]), Long.parseLong(splited[1]));
-                })
-                .collectMap(Pair::getKey, Pair::getValue)
-                .map(positions -> new ConsumerPosition(seekType != null ? seekType : SeekType.BEGINNING, positions));
-    }
-}

+ 8 - 10
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/service/ClusterService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClusterService.java

@@ -1,13 +1,11 @@
-package com.provectus.kafka.ui.cluster.service;
-
-import com.provectus.kafka.ui.cluster.exception.NotFoundException;
-import com.provectus.kafka.ui.cluster.mapper.ClusterMapper;
-import com.provectus.kafka.ui.cluster.model.ClustersStorage;
-import com.provectus.kafka.ui.cluster.model.ConsumerPosition;
-import com.provectus.kafka.ui.cluster.model.InternalTopic;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
-import com.provectus.kafka.ui.cluster.util.ClusterUtil;
-import com.provectus.kafka.ui.kafka.KafkaService;
+package com.provectus.kafka.ui.service;
+
+import com.provectus.kafka.ui.exception.NotFoundException;
+import com.provectus.kafka.ui.mapper.ClusterMapper;
+import com.provectus.kafka.ui.model.ConsumerPosition;
+import com.provectus.kafka.ui.model.InternalTopic;
+import com.provectus.kafka.ui.model.KafkaCluster;
+import com.provectus.kafka.ui.util.ClusterUtil;
 import com.provectus.kafka.ui.model.*;
 import com.provectus.kafka.ui.model.*;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.SneakyThrows;
 import lombok.SneakyThrows;

+ 1 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/ClustersMetricsScheduler.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClustersMetricsScheduler.java

@@ -1,7 +1,5 @@
-package com.provectus.kafka.ui.cluster;
+package com.provectus.kafka.ui.service;
 
 
-import com.provectus.kafka.ui.cluster.model.ClustersStorage;
-import com.provectus.kafka.ui.cluster.service.MetricsUpdateService;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.scheduling.annotation.Scheduled;

+ 4 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/model/ClustersStorage.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClustersStorage.java

@@ -1,7 +1,8 @@
-package com.provectus.kafka.ui.cluster.model;
+package com.provectus.kafka.ui.service;
 
 
-import com.provectus.kafka.ui.cluster.config.ClustersProperties;
-import com.provectus.kafka.ui.cluster.mapper.ClusterMapper;
+import com.provectus.kafka.ui.config.ClustersProperties;
+import com.provectus.kafka.ui.mapper.ClusterMapper;
+import com.provectus.kafka.ui.model.KafkaCluster;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.mapstruct.factory.Mappers;
 import org.mapstruct.factory.Mappers;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;

+ 6 - 7
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/service/ConsumingService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ConsumingService.java

@@ -1,13 +1,12 @@
-package com.provectus.kafka.ui.cluster.service;
+package com.provectus.kafka.ui.service;
 
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.provectus.kafka.ui.cluster.deserialization.DeserializationService;
-import com.provectus.kafka.ui.cluster.deserialization.RecordDeserializer;
-import com.provectus.kafka.ui.cluster.model.ConsumerPosition;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
-import com.provectus.kafka.ui.cluster.util.ClusterUtil;
-import com.provectus.kafka.ui.kafka.KafkaService;
+import com.provectus.kafka.ui.deserialization.DeserializationService;
+import com.provectus.kafka.ui.deserialization.RecordDeserializer;
+import com.provectus.kafka.ui.model.ConsumerPosition;
+import com.provectus.kafka.ui.model.KafkaCluster;
+import com.provectus.kafka.ui.util.ClusterUtil;
 import com.provectus.kafka.ui.model.SeekType;
 import com.provectus.kafka.ui.model.SeekType;
 import com.provectus.kafka.ui.model.TopicMessage;
 import com.provectus.kafka.ui.model.TopicMessage;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;

+ 8 - 10
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/service/KafkaConnectService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/KafkaConnectService.java

@@ -1,12 +1,11 @@
-package com.provectus.kafka.ui.cluster.service;
-
-import com.provectus.kafka.ui.cluster.client.KafkaConnectClients;
-import com.provectus.kafka.ui.cluster.exception.NotFoundException;
-import com.provectus.kafka.ui.cluster.mapper.ClusterMapper;
-import com.provectus.kafka.ui.cluster.mapper.KafkaConnectMapper;
-import com.provectus.kafka.ui.cluster.model.ClustersStorage;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
-import com.provectus.kafka.ui.cluster.model.KafkaConnectCluster;
+package com.provectus.kafka.ui.service;
+
+import com.provectus.kafka.ui.client.KafkaConnectClients;
+import com.provectus.kafka.ui.exception.NotFoundException;
+import com.provectus.kafka.ui.mapper.ClusterMapper;
+import com.provectus.kafka.ui.mapper.KafkaConnectMapper;
+import com.provectus.kafka.ui.model.KafkaCluster;
+import com.provectus.kafka.ui.model.KafkaConnectCluster;
 import com.provectus.kafka.ui.model.*;
 import com.provectus.kafka.ui.model.*;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;
@@ -38,7 +37,6 @@ public class KafkaConnectService {
         );
         );
     }
     }
 
 
-
     public Flux<String> getConnectors(String clusterName, String connectName) {
     public Flux<String> getConnectors(String clusterName, String connectName) {
         return getConnectAddress(clusterName, connectName)
         return getConnectAddress(clusterName, connectName)
                 .flatMapMany(connect ->
                 .flatMapMany(connect ->

+ 6 - 7
kafka-ui-api/src/main/java/com/provectus/kafka/ui/kafka/KafkaService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/KafkaService.java

@@ -1,15 +1,14 @@
-package com.provectus.kafka.ui.kafka;
+package com.provectus.kafka.ui.service;
 
 
-import com.provectus.kafka.ui.cluster.model.*;
-import com.provectus.kafka.ui.cluster.util.ClusterUtil;
-import com.provectus.kafka.ui.cluster.util.JmxClusterUtil;
-import com.provectus.kafka.ui.cluster.util.JmxMetricsName;
-import com.provectus.kafka.ui.cluster.util.JmxMetricsValueName;
+import com.provectus.kafka.ui.model.*;
+import com.provectus.kafka.ui.util.ClusterUtil;
+import com.provectus.kafka.ui.util.JmxClusterUtil;
+import com.provectus.kafka.ui.util.JmxMetricsName;
+import com.provectus.kafka.ui.util.JmxMetricsValueName;
 import com.provectus.kafka.ui.model.ConsumerGroup;
 import com.provectus.kafka.ui.model.ConsumerGroup;
 import com.provectus.kafka.ui.model.Metric;
 import com.provectus.kafka.ui.model.Metric;
 import com.provectus.kafka.ui.model.ServerStatus;
 import com.provectus.kafka.ui.model.ServerStatus;
 import com.provectus.kafka.ui.model.TopicFormData;
 import com.provectus.kafka.ui.model.TopicFormData;
-import com.provectus.kafka.ui.zookeeper.ZookeeperService;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.SneakyThrows;
 import lombok.SneakyThrows;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;

+ 2 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/service/MetricsUpdateService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/MetricsUpdateService.java

@@ -1,7 +1,6 @@
-package com.provectus.kafka.ui.cluster.service;
+package com.provectus.kafka.ui.service;
 
 
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
-import com.provectus.kafka.ui.kafka.KafkaService;
+import com.provectus.kafka.ui.model.KafkaCluster;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;

+ 10 - 11
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/service/SchemaRegistryService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/SchemaRegistryService.java

@@ -1,15 +1,14 @@
-package com.provectus.kafka.ui.cluster.service;
+package com.provectus.kafka.ui.service;
 
 
-import com.provectus.kafka.ui.cluster.exception.DuplicateEntityException;
-import com.provectus.kafka.ui.cluster.exception.NotFoundException;
-import com.provectus.kafka.ui.cluster.exception.UnprocessableEntityException;
-import com.provectus.kafka.ui.cluster.mapper.ClusterMapper;
-import com.provectus.kafka.ui.cluster.model.ClustersStorage;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
-import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibilityCheck;
-import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalCompatibilityLevel;
-import com.provectus.kafka.ui.cluster.model.schemaregistry.InternalNewSchema;
-import com.provectus.kafka.ui.cluster.model.schemaregistry.SubjectIdResponse;
+import com.provectus.kafka.ui.exception.DuplicateEntityException;
+import com.provectus.kafka.ui.exception.NotFoundException;
+import com.provectus.kafka.ui.exception.UnprocessableEntityException;
+import com.provectus.kafka.ui.mapper.ClusterMapper;
+import com.provectus.kafka.ui.model.KafkaCluster;
+import com.provectus.kafka.ui.model.schemaregistry.InternalCompatibilityCheck;
+import com.provectus.kafka.ui.model.schemaregistry.InternalCompatibilityLevel;
+import com.provectus.kafka.ui.model.schemaregistry.InternalNewSchema;
+import com.provectus.kafka.ui.model.schemaregistry.SubjectIdResponse;
 import com.provectus.kafka.ui.model.*;
 import com.provectus.kafka.ui.model.*;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;

+ 2 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/zookeeper/ZookeeperService.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ZookeeperService.java

@@ -1,13 +1,12 @@
-package com.provectus.kafka.ui.zookeeper;
+package com.provectus.kafka.ui.service;
 
 
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
+import com.provectus.kafka.ui.model.KafkaCluster;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import lombok.extern.log4j.Log4j2;
 import org.I0Itec.zkclient.ZkClient;
 import org.I0Itec.zkclient.ZkClient;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 
 
 @Service
 @Service

+ 3 - 4
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/util/ClusterUtil.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/ClusterUtil.java

@@ -1,7 +1,6 @@
-package com.provectus.kafka.ui.cluster.util;
+package com.provectus.kafka.ui.util;
 
 
-import com.provectus.kafka.ui.cluster.deserialization.RecordDeserializer;
-import com.provectus.kafka.ui.cluster.model.*;
+import com.provectus.kafka.ui.deserialization.RecordDeserializer;
 import com.provectus.kafka.ui.model.*;
 import com.provectus.kafka.ui.model.*;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.kafka.clients.admin.*;
 import org.apache.kafka.clients.admin.*;
@@ -22,7 +21,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.Stream;
 
 
-import static com.provectus.kafka.ui.kafka.KafkaConstants.TOPIC_DEFAULT_CONFIGS;
+import static com.provectus.kafka.ui.util.KafkaConstants.TOPIC_DEFAULT_CONFIGS;
 import static org.apache.kafka.common.config.TopicConfig.MESSAGE_FORMAT_VERSION_CONFIG;
 import static org.apache.kafka.common.config.TopicConfig.MESSAGE_FORMAT_VERSION_CONFIG;
 
 
 @Slf4j
 @Slf4j

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/util/JmxClusterUtil.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxClusterUtil.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.util;
+package com.provectus.kafka.ui.util;
 
 
 import com.provectus.kafka.ui.model.Metric;
 import com.provectus.kafka.ui.model.Metric;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/util/JmxMetricsName.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxMetricsName.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.util;
+package com.provectus.kafka.ui.util;
 
 
 public enum JmxMetricsName {
 public enum JmxMetricsName {
     MessagesInPerSec,
     MessagesInPerSec,

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/util/JmxMetricsValueName.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxMetricsValueName.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.util;
+package com.provectus.kafka.ui.util;
 
 
 public enum  JmxMetricsValueName {
 public enum  JmxMetricsValueName {
     Count,
     Count,

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/cluster/util/JmxPoolFactory.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/JmxPoolFactory.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.cluster.util;
+package com.provectus.kafka.ui.util;
 
 
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
 import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;

+ 1 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/kafka/KafkaConstants.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/KafkaConstants.java

@@ -1,4 +1,4 @@
-package com.provectus.kafka.ui.kafka;
+package com.provectus.kafka.ui.util;
 
 
 import java.util.AbstractMap;
 import java.util.AbstractMap;
 import java.util.Map;
 import java.util.Map;

+ 9 - 4
kafka-ui-api/src/test/java/com/provectus/kafka/ui/SchemaRegistryServiceTests.java

@@ -65,7 +65,7 @@ class SchemaRegistryServiceTests extends AbstractBaseTest {
                 .post()
                 .post()
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .contentType(MediaType.APPLICATION_JSON)
                 .contentType(MediaType.APPLICATION_JSON)
-                .body(BodyInserters.fromValue(schema.formatted(subject)))
+                .body(BodyInserters.fromValue(String.format(schema, subject)))
                 .exchange()
                 .exchange()
                 .expectStatus().isBadRequest();
                 .expectStatus().isBadRequest();
     }
     }
@@ -78,7 +78,7 @@ class SchemaRegistryServiceTests extends AbstractBaseTest {
                 .post()
                 .post()
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .contentType(MediaType.APPLICATION_JSON)
                 .contentType(MediaType.APPLICATION_JSON)
-                .body(BodyInserters.fromValue(schema.formatted(subject)))
+                .body(BodyInserters.fromValue(String.format(schema, subject)))
                 .exchange()
                 .exchange()
                 .expectStatus().isEqualTo(HttpStatus.OK);
                 .expectStatus().isEqualTo(HttpStatus.OK);
 
 
@@ -86,7 +86,7 @@ class SchemaRegistryServiceTests extends AbstractBaseTest {
                 .post()
                 .post()
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .contentType(MediaType.APPLICATION_JSON)
                 .contentType(MediaType.APPLICATION_JSON)
-                .body(BodyInserters.fromValue(schema.formatted(subject)))
+                .body(BodyInserters.fromValue(String.format(schema, subject)))
                 .exchange()
                 .exchange()
                 .expectStatus().isEqualTo(HttpStatus.CONFLICT);
                 .expectStatus().isEqualTo(HttpStatus.CONFLICT);
     }
     }
@@ -201,7 +201,12 @@ class SchemaRegistryServiceTests extends AbstractBaseTest {
                 .post()
                 .post()
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .uri("/api/clusters/{clusterName}/schemas", LOCAL)
                 .contentType(MediaType.APPLICATION_JSON)
                 .contentType(MediaType.APPLICATION_JSON)
-                .body(BodyInserters.fromValue("{\"subject\":\"%s\",\"schemaType\":\"AVRO\",\"schema\":\"{\\\"type\\\": \\\"string\\\"}\"}".formatted(subject)))
+                .body(BodyInserters.fromValue(
+                    String.format(
+                        "{\"subject\":\"%s\",\"schemaType\":\"AVRO\",\"schema\":\"{\\\"type\\\": \\\"string\\\"}\"}",
+                        subject
+                    )
+                ))
                 .exchange()
                 .exchange()
                 .expectStatus().isOk()
                 .expectStatus().isOk()
                 .expectBody(SchemaSubject.class)
                 .expectBody(SchemaSubject.class)

+ 2 - 2
kafka-ui-api/src/test/java/com/provectus/kafka/ui/cluster/deserialization/SchemaRegistryRecordDeserializerTest.java → kafka-ui-api/src/test/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializerTest.java

@@ -1,7 +1,7 @@
-package com.provectus.kafka.ui.cluster.deserialization;
+package com.provectus.kafka.ui.deserialization;
 
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.provectus.kafka.ui.cluster.model.KafkaCluster;
+import com.provectus.kafka.ui.model.KafkaCluster;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.common.utils.Bytes;
 import org.apache.kafka.common.utils.Bytes;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;

+ 15 - 15
kafka-ui-contract/src/main/resources/swagger/kafka-connect-api.yaml

@@ -17,7 +17,7 @@ paths:
   /connectors:
   /connectors:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get all connectors from Kafka Connect service
       summary: get all connectors from Kafka Connect service
       operationId: getConnectors
       operationId: getConnectors
       responses:
       responses:
@@ -31,7 +31,7 @@ paths:
                   type: string
                   type: string
     post:
     post:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: create new connector
       summary: create new connector
       operationId: createConnector
       operationId: createConnector
       requestBody:
       requestBody:
@@ -56,7 +56,7 @@ paths:
   /connectors/{connectorName}:
   /connectors/{connectorName}:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get information about the connector
       summary: get information about the connector
       operationId: getConnector
       operationId: getConnector
       parameters:
       parameters:
@@ -74,7 +74,7 @@ paths:
                 $ref: '#/components/schemas/Connector'
                 $ref: '#/components/schemas/Connector'
     delete:
     delete:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: delete connector
       summary: delete connector
       operationId: deleteConnector
       operationId: deleteConnector
       parameters:
       parameters:
@@ -92,7 +92,7 @@ paths:
   /connectors/{connectorName}/config:
   /connectors/{connectorName}/config:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get connector configuration
       summary: get connector configuration
       operationId: getConnectorConfig
       operationId: getConnectorConfig
       parameters:
       parameters:
@@ -110,7 +110,7 @@ paths:
                 $ref: '#/components/schemas/ConnectorConfig'
                 $ref: '#/components/schemas/ConnectorConfig'
     put:
     put:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: update or create connector with provided config
       summary: update or create connector with provided config
       operationId: setConnectorConfig
       operationId: setConnectorConfig
       parameters:
       parameters:
@@ -142,7 +142,7 @@ paths:
   /connectors/{connectorName}/status:
   /connectors/{connectorName}/status:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get connector status
       summary: get connector status
       operationId: getConnectorStatus
       operationId: getConnectorStatus
       parameters:
       parameters:
@@ -162,7 +162,7 @@ paths:
   /connectors/{connectorName}/restart:
   /connectors/{connectorName}/restart:
     post:
     post:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: restart the connector
       summary: restart the connector
       operationId: restartConnector
       operationId: restartConnector
       parameters:
       parameters:
@@ -180,7 +180,7 @@ paths:
   /connectors/{connectorName}/pause:
   /connectors/{connectorName}/pause:
     put:
     put:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: pause the connector
       summary: pause the connector
       operationId: pauseConnector
       operationId: pauseConnector
       parameters:
       parameters:
@@ -196,7 +196,7 @@ paths:
   /connectors/{connectorName}/resume:
   /connectors/{connectorName}/resume:
     put:
     put:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: resume the connector
       summary: resume the connector
       operationId: resumeConnector
       operationId: resumeConnector
       parameters:
       parameters:
@@ -212,7 +212,7 @@ paths:
   /connectors/{connectorName}/tasks:
   /connectors/{connectorName}/tasks:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get connector tasks
       summary: get connector tasks
       operationId: getConnectorTasks
       operationId: getConnectorTasks
       parameters:
       parameters:
@@ -234,7 +234,7 @@ paths:
   /connectors/{connectorName}/tasks/{taskId}/status:
   /connectors/{connectorName}/tasks/{taskId}/status:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get connector task status
       summary: get connector task status
       operationId: getConnectorTaskStatus
       operationId: getConnectorTaskStatus
       parameters:
       parameters:
@@ -259,7 +259,7 @@ paths:
   /connectors/{connectorName}/tasks/{taskId}/restart:
   /connectors/{connectorName}/tasks/{taskId}/restart:
     post:
     post:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: restart connector task
       summary: restart connector task
       operationId: restartConnectorTask
       operationId: restartConnectorTask
       parameters:
       parameters:
@@ -280,7 +280,7 @@ paths:
   /connector-plugins:
   /connector-plugins:
     get:
     get:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: get connector plugins
       summary: get connector plugins
       operationId: getConnectorPlugins
       operationId: getConnectorPlugins
       responses:
       responses:
@@ -296,7 +296,7 @@ paths:
   /connector-plugins/{pluginName}/config/validate:
   /connector-plugins/{pluginName}/config/validate:
     put:
     put:
       tags:
       tags:
-        - /connect
+        - KafkaConnectClient
       summary: validate connector plugin configuration
       summary: validate connector plugin configuration
       operationId: validateConnectorPluginConfig
       operationId: validateConnectorPluginConfig
       parameters:
       parameters:

+ 39 - 39
kafka-ui-contract/src/main/resources/swagger/kafka-ui-api.yaml

@@ -18,7 +18,7 @@ paths:
   /api/clusters:
   /api/clusters:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Clusters
       summary: getClusters
       summary: getClusters
       operationId: getClusters
       operationId: getClusters
       responses:
       responses:
@@ -34,7 +34,7 @@ paths:
   /api/clusters/{clusterName}/brokers:
   /api/clusters/{clusterName}/brokers:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Brokers
       summary: getBrokers
       summary: getBrokers
       operationId: getBrokers
       operationId: getBrokers
       parameters:
       parameters:
@@ -56,7 +56,7 @@ paths:
   /api/clusters/{clusterName}/metrics:
   /api/clusters/{clusterName}/metrics:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Clusters
       summary: getClusterMetrics
       summary: getClusterMetrics
       operationId: getClusterMetrics
       operationId: getClusterMetrics
       parameters:
       parameters:
@@ -76,7 +76,7 @@ paths:
   /api/clusters/{clusterName}/stats:
   /api/clusters/{clusterName}/stats:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Clusters
       summary: getClusterStats
       summary: getClusterStats
       operationId: getClusterStats
       operationId: getClusterStats
       parameters:
       parameters:
@@ -96,7 +96,7 @@ paths:
   /api/clusters/{clusterName}/brokers/{id}/metrics:
   /api/clusters/{clusterName}/brokers/{id}/metrics:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Brokers
       summary: getBrokersMetrics
       summary: getBrokersMetrics
       operationId: getBrokersMetrics
       operationId: getBrokersMetrics
       parameters:
       parameters:
@@ -121,7 +121,7 @@ paths:
   /api/clusters/{clusterName}/topics:
   /api/clusters/{clusterName}/topics:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Topics
       summary: getTopics
       summary: getTopics
       operationId: getTopics
       operationId: getTopics
       parameters:
       parameters:
@@ -141,7 +141,7 @@ paths:
                   $ref: '#/components/schemas/Topic'
                   $ref: '#/components/schemas/Topic'
     post:
     post:
       tags:
       tags:
-        - /api/clusters
+        - Topics
       summary: createTopic
       summary: createTopic
       operationId: createTopic
       operationId: createTopic
       parameters:
       parameters:
@@ -166,7 +166,7 @@ paths:
   /api/clusters/{clusterName}/topics/{topicName}:
   /api/clusters/{clusterName}/topics/{topicName}:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Topics
       summary: getTopicDetails
       summary: getTopicDetails
       operationId: getTopicDetails
       operationId: getTopicDetails
       parameters:
       parameters:
@@ -189,7 +189,7 @@ paths:
                 $ref: '#/components/schemas/TopicDetails'
                 $ref: '#/components/schemas/TopicDetails'
     patch:
     patch:
       tags:
       tags:
-        - /api/clusters
+        - Topics
       summary: updateTopic
       summary: updateTopic
       operationId: updateTopic
       operationId: updateTopic
       parameters:
       parameters:
@@ -217,7 +217,7 @@ paths:
                 $ref: '#/components/schemas/Topic'
                 $ref: '#/components/schemas/Topic'
     delete:
     delete:
       tags:
       tags:
-        - /api/clusters
+        - Topics
       summary: deleteTopic
       summary: deleteTopic
       operationId: deleteTopic
       operationId: deleteTopic
       parameters:
       parameters:
@@ -240,7 +240,7 @@ paths:
   /api/clusters/{clusterName}/topics/{topicName}/config:
   /api/clusters/{clusterName}/topics/{topicName}/config:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Topics
       summary: getTopicConfigs
       summary: getTopicConfigs
       operationId: getTopicConfigs
       operationId: getTopicConfigs
       parameters:
       parameters:
@@ -267,7 +267,7 @@ paths:
   /api/clusters/{clusterName}/topics/{topicName}/messages:
   /api/clusters/{clusterName}/topics/{topicName}/messages:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Messages
       summary: getTopicMessages
       summary: getTopicMessages
       operationId: getTopicMessages
       operationId: getTopicMessages
       parameters:
       parameters:
@@ -311,7 +311,7 @@ paths:
                   $ref: '#/components/schemas/TopicMessage'
                   $ref: '#/components/schemas/TopicMessage'
     delete:
     delete:
       tags:
       tags:
-        - /api/clusters
+        - Messages
       summary: deleteTopicMessages
       summary: deleteTopicMessages
       operationId: deleteTopicMessages
       operationId: deleteTopicMessages
       parameters:
       parameters:
@@ -341,7 +341,7 @@ paths:
   /api/clusters/{clusterName}/consumer-groups/{id}:
   /api/clusters/{clusterName}/consumer-groups/{id}:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Consumer Groups
       summary: get Consumer Group By Id
       summary: get Consumer Group By Id
       operationId: getConsumerGroup
       operationId: getConsumerGroup
       parameters:
       parameters:
@@ -366,7 +366,7 @@ paths:
   /api/clusters/{clusterName}/consumerGroups:
   /api/clusters/{clusterName}/consumerGroups:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Consumer Groups
       summary: get all ConsumerGroups
       summary: get all ConsumerGroups
       operationId: getConsumerGroups
       operationId: getConsumerGroups
       parameters:
       parameters:
@@ -388,7 +388,7 @@ paths:
   /api/clusters/{clusterName}/schemas:
   /api/clusters/{clusterName}/schemas:
     post:
     post:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: create a new subject schema
       summary: create a new subject schema
       operationId: createNewSchema
       operationId: createNewSchema
       parameters:
       parameters:
@@ -417,7 +417,7 @@ paths:
           description: Invalid parameters
           description: Invalid parameters
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: get all schemas of latest version from Schema Registry service
       summary: get all schemas of latest version from Schema Registry service
       operationId: getSchemas
       operationId: getSchemas
       parameters:
       parameters:
@@ -439,7 +439,7 @@ paths:
   /api/clusters/{clusterName}/schemas/{subject}:
   /api/clusters/{clusterName}/schemas/{subject}:
     delete:
     delete:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: delete schema from Schema Registry service
       summary: delete schema from Schema Registry service
       operationId: deleteSchema
       operationId: deleteSchema
       parameters:
       parameters:
@@ -462,7 +462,7 @@ paths:
   /api/clusters/{clusterName}/schemas/{subject}/versions:
   /api/clusters/{clusterName}/schemas/{subject}/versions:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: get all version of subject from Schema Registry service
       summary: get all version of subject from Schema Registry service
       operationId: getAllVersionsBySubject
       operationId: getAllVersionsBySubject
       parameters:
       parameters:
@@ -489,7 +489,7 @@ paths:
   /api/clusters/{clusterName}/schemas/{subject}/latest:
   /api/clusters/{clusterName}/schemas/{subject}/latest:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: get the latest schema from Schema Registry service
       summary: get the latest schema from Schema Registry service
       operationId: getLatestSchema
       operationId: getLatestSchema
       parameters:
       parameters:
@@ -512,7 +512,7 @@ paths:
                 $ref: '#/components/schemas/SchemaSubject'
                 $ref: '#/components/schemas/SchemaSubject'
     delete:
     delete:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: delete the latest schema from schema registry
       summary: delete the latest schema from schema registry
       operationId: deleteLatestSchema
       operationId: deleteLatestSchema
       parameters:
       parameters:
@@ -536,7 +536,7 @@ paths:
   /api/clusters/{clusterName}/schemas/{subject}/versions/{version}:
   /api/clusters/{clusterName}/schemas/{subject}/versions/{version}:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: get schema by version from Schema Registry service
       summary: get schema by version from Schema Registry service
       operationId: getSchemaByVersion
       operationId: getSchemaByVersion
       parameters:
       parameters:
@@ -564,7 +564,7 @@ paths:
                 $ref: '#/components/schemas/SchemaSubject'
                 $ref: '#/components/schemas/SchemaSubject'
     delete:
     delete:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: delete schema by version from schema registry
       summary: delete schema by version from schema registry
       operationId: deleteSchemaByVersion
       operationId: deleteSchemaByVersion
       parameters:
       parameters:
@@ -592,7 +592,7 @@ paths:
   /api/clusters/{clusterName}/schemas/compatibility:
   /api/clusters/{clusterName}/schemas/compatibility:
     get:
     get:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: Get global schema compatibility level
       summary: Get global schema compatibility level
       operationId: getGlobalSchemaCompatibilityLevel
       operationId: getGlobalSchemaCompatibilityLevel
       parameters:
       parameters:
@@ -610,7 +610,7 @@ paths:
                 $ref: '#/components/schemas/CompatibilityLevel'
                 $ref: '#/components/schemas/CompatibilityLevel'
     put:
     put:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: Update compatibility level globally
       summary: Update compatibility level globally
       operationId: updateGlobalSchemaCompatibilityLevel
       operationId: updateGlobalSchemaCompatibilityLevel
       parameters:
       parameters:
@@ -633,7 +633,7 @@ paths:
   /api/clusters/{clusterName}/schemas/{subject}/compatibility:
   /api/clusters/{clusterName}/schemas/{subject}/compatibility:
     put:
     put:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: Update compatibility level for specific schema.
       summary: Update compatibility level for specific schema.
       operationId: updateSchemaCompatibilityLevel
       operationId: updateSchemaCompatibilityLevel
       parameters:
       parameters:
@@ -661,7 +661,7 @@ paths:
   /api/clusters/{clusterName}/schemas/{subject}/check:
   /api/clusters/{clusterName}/schemas/{subject}/check:
     post:
     post:
       tags:
       tags:
-        - /api/clusters
+        - Schemas
       summary: Check compatibility of the schema.
       summary: Check compatibility of the schema.
       operationId: checkSchemaCompatibility
       operationId: checkSchemaCompatibility
       parameters:
       parameters:
@@ -693,7 +693,7 @@ paths:
   /api/clusters/{clusterName}/connects:
   /api/clusters/{clusterName}/connects:
     get:
     get:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: get all kafka connect instances
       summary: get all kafka connect instances
       operationId: getConnects
       operationId: getConnects
       parameters:
       parameters:
@@ -715,7 +715,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/connectors:
   /api/clusters/{clusterName}/connects/{connectName}/connectors:
     get:
     get:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: get all connectors from Kafka Connect service
       summary: get all connectors from Kafka Connect service
       operationId: getConnectors
       operationId: getConnectors
       parameters:
       parameters:
@@ -740,7 +740,7 @@ paths:
                   type: string
                   type: string
     post:
     post:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: create new connector
       summary: create new connector
       operationId: createConnector
       operationId: createConnector
       parameters:
       parameters:
@@ -772,7 +772,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}:
     get:
     get:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: get information about the connector
       summary: get information about the connector
       operationId: getConnector
       operationId: getConnector
       parameters:
       parameters:
@@ -800,7 +800,7 @@ paths:
                 $ref: '#/components/schemas/Connector'
                 $ref: '#/components/schemas/Connector'
     delete:
     delete:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: delete connector
       summary: delete connector
       operationId: deleteConnector
       operationId: deleteConnector
       parameters:
       parameters:
@@ -828,7 +828,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/action/{action}:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/action/{action}:
     post:
     post:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: update connector state (restart, pause or resume)
       summary: update connector state (restart, pause or resume)
       operationId: updateConnectorState
       operationId: updateConnectorState
       parameters:
       parameters:
@@ -861,7 +861,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/config:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/config:
     get:
     get:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: get connector configuration
       summary: get connector configuration
       operationId: getConnectorConfig
       operationId: getConnectorConfig
       parameters:
       parameters:
@@ -889,7 +889,7 @@ paths:
                 $ref: '#/components/schemas/ConnectorConfig'
                 $ref: '#/components/schemas/ConnectorConfig'
     put:
     put:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: update or create connector with provided config
       summary: update or create connector with provided config
       operationId: setConnectorConfig
       operationId: setConnectorConfig
       parameters:
       parameters:
@@ -926,7 +926,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/tasks:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/tasks:
     get:
     get:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: get connector tasks
       summary: get connector tasks
       operationId: getConnectorTasks
       operationId: getConnectorTasks
       parameters:
       parameters:
@@ -958,7 +958,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/tasks/{taskId}/action/restart:
   /api/clusters/{clusterName}/connects/{connectName}/connectors/{connectorName}/tasks/{taskId}/action/restart:
     post:
     post:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: restart connector task
       summary: restart connector task
       operationId: restartConnectorTask
       operationId: restartConnectorTask
       parameters:
       parameters:
@@ -989,7 +989,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/plugins:
   /api/clusters/{clusterName}/connects/{connectName}/plugins:
     get:
     get:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: get connector plugins
       summary: get connector plugins
       operationId: getConnectorPlugins
       operationId: getConnectorPlugins
       parameters:
       parameters:
@@ -1016,7 +1016,7 @@ paths:
   /api/clusters/{clusterName}/connects/{connectName}/plugins/{pluginName}/config/validate:
   /api/clusters/{clusterName}/connects/{connectName}/plugins/{pluginName}/config/validate:
     put:
     put:
       tags:
       tags:
-        - /api/clusters/connects
+        - Kafka Connect
       summary: validate connector plugin configuration
       summary: validate connector plugin configuration
       operationId: validateConnectorPluginConfig
       operationId: validateConnectorPluginConfig
       parameters:
       parameters:

+ 38 - 21
kafka-ui-react-app/src/redux/actions/thunks.ts

@@ -1,5 +1,10 @@
 import {
 import {
-  ApiClustersApi,
+  ClustersApi,
+  BrokersApi,
+  TopicsApi,
+  ConsumerGroupsApi,
+  SchemasApi,
+  MessagesApi,
   Configuration,
   Configuration,
   Cluster,
   Cluster,
   Topic,
   Topic,
@@ -24,12 +29,17 @@ import { BASE_PARAMS } from 'lib/constants';
 import * as actions from './actions';
 import * as actions from './actions';
 
 
 const apiClientConf = new Configuration(BASE_PARAMS);
 const apiClientConf = new Configuration(BASE_PARAMS);
-export const apiClient = new ApiClustersApi(apiClientConf);
+export const clustersApiClient = new ClustersApi(apiClientConf);
+export const brokersApiClient = new BrokersApi(apiClientConf);
+export const topicsApiClient = new TopicsApi(apiClientConf);
+export const consumerGroupsApiClient = new ConsumerGroupsApi(apiClientConf);
+export const schemasApiClient = new SchemasApi(apiClientConf);
+export const messagesApiClient = new MessagesApi(apiClientConf);
 
 
 export const fetchClustersList = (): PromiseThunkResult => async (dispatch) => {
 export const fetchClustersList = (): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchClusterListAction.request());
   dispatch(actions.fetchClusterListAction.request());
   try {
   try {
-    const clusters: Cluster[] = await apiClient.getClusters();
+    const clusters: Cluster[] = await clustersApiClient.getClusters();
     dispatch(actions.fetchClusterListAction.success(clusters));
     dispatch(actions.fetchClusterListAction.success(clusters));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchClusterListAction.failure());
     dispatch(actions.fetchClusterListAction.failure());
@@ -41,7 +51,7 @@ export const fetchClusterStats = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchClusterStatsAction.request());
   dispatch(actions.fetchClusterStatsAction.request());
   try {
   try {
-    const payload = await apiClient.getClusterStats({ clusterName });
+    const payload = await clustersApiClient.getClusterStats({ clusterName });
     dispatch(actions.fetchClusterStatsAction.success(payload));
     dispatch(actions.fetchClusterStatsAction.success(payload));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchClusterStatsAction.failure());
     dispatch(actions.fetchClusterStatsAction.failure());
@@ -53,7 +63,7 @@ export const fetchClusterMetrics = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchClusterMetricsAction.request());
   dispatch(actions.fetchClusterMetricsAction.request());
   try {
   try {
-    const payload = await apiClient.getClusterMetrics({ clusterName });
+    const payload = await clustersApiClient.getClusterMetrics({ clusterName });
     dispatch(actions.fetchClusterMetricsAction.success(payload));
     dispatch(actions.fetchClusterMetricsAction.success(payload));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchClusterMetricsAction.failure());
     dispatch(actions.fetchClusterMetricsAction.failure());
@@ -65,7 +75,7 @@ export const fetchBrokers = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchBrokersAction.request());
   dispatch(actions.fetchBrokersAction.request());
   try {
   try {
-    const payload = await apiClient.getBrokers({ clusterName });
+    const payload = await brokersApiClient.getBrokers({ clusterName });
     dispatch(actions.fetchBrokersAction.success(payload));
     dispatch(actions.fetchBrokersAction.success(payload));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchBrokersAction.failure());
     dispatch(actions.fetchBrokersAction.failure());
@@ -78,7 +88,7 @@ export const fetchBrokerMetrics = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchBrokerMetricsAction.request());
   dispatch(actions.fetchBrokerMetricsAction.request());
   try {
   try {
-    const payload = await apiClient.getBrokersMetrics({
+    const payload = await brokersApiClient.getBrokersMetrics({
       clusterName,
       clusterName,
       id: brokerId,
       id: brokerId,
     });
     });
@@ -93,7 +103,7 @@ export const fetchTopicsList = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchTopicsListAction.request());
   dispatch(actions.fetchTopicsListAction.request());
   try {
   try {
-    const topics = await apiClient.getTopics({ clusterName });
+    const topics = await topicsApiClient.getTopics({ clusterName });
     dispatch(actions.fetchTopicsListAction.success(topics));
     dispatch(actions.fetchTopicsListAction.success(topics));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchTopicsListAction.failure());
     dispatch(actions.fetchTopicsListAction.failure());
@@ -107,7 +117,7 @@ export const fetchTopicMessages = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchTopicMessagesAction.request());
   dispatch(actions.fetchTopicMessagesAction.request());
   try {
   try {
-    const messages = await apiClient.getTopicMessages({
+    const messages = await messagesApiClient.getTopicMessages({
       clusterName,
       clusterName,
       topicName,
       topicName,
       ...queryParams,
       ...queryParams,
@@ -124,7 +134,7 @@ export const fetchTopicDetails = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchTopicDetailsAction.request());
   dispatch(actions.fetchTopicDetailsAction.request());
   try {
   try {
-    const topicDetails = await apiClient.getTopicDetails({
+    const topicDetails = await topicsApiClient.getTopicDetails({
       clusterName,
       clusterName,
       topicName,
       topicName,
     });
     });
@@ -145,7 +155,10 @@ export const fetchTopicConfig = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchTopicConfigAction.request());
   dispatch(actions.fetchTopicConfigAction.request());
   try {
   try {
-    const config = await apiClient.getTopicConfigs({ clusterName, topicName });
+    const config = await topicsApiClient.getTopicConfigs({
+      clusterName,
+      topicName,
+    });
     dispatch(actions.fetchTopicConfigAction.success({ topicName, config }));
     dispatch(actions.fetchTopicConfigAction.success({ topicName, config }));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchTopicConfigAction.failure());
     dispatch(actions.fetchTopicConfigAction.failure());
@@ -194,7 +207,7 @@ export const createTopic = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.createTopicAction.request());
   dispatch(actions.createTopicAction.request());
   try {
   try {
-    const topic: Topic = await apiClient.createTopic({
+    const topic: Topic = await topicsApiClient.createTopic({
       clusterName,
       clusterName,
       topicFormData: formatTopicFormData(form),
       topicFormData: formatTopicFormData(form),
     });
     });
@@ -210,7 +223,7 @@ export const updateTopic = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.updateTopicAction.request());
   dispatch(actions.updateTopicAction.request());
   try {
   try {
-    const topic: Topic = await apiClient.updateTopic({
+    const topic: Topic = await topicsApiClient.updateTopic({
       clusterName,
       clusterName,
       topicName: form.name,
       topicName: form.name,
       topicFormData: formatTopicFormData(form),
       topicFormData: formatTopicFormData(form),
@@ -226,7 +239,9 @@ export const fetchConsumerGroupsList = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchConsumerGroupsAction.request());
   dispatch(actions.fetchConsumerGroupsAction.request());
   try {
   try {
-    const consumerGroups = await apiClient.getConsumerGroups({ clusterName });
+    const consumerGroups = await consumerGroupsApiClient.getConsumerGroups({
+      clusterName,
+    });
     dispatch(actions.fetchConsumerGroupsAction.success(consumerGroups));
     dispatch(actions.fetchConsumerGroupsAction.success(consumerGroups));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchConsumerGroupsAction.failure());
     dispatch(actions.fetchConsumerGroupsAction.failure());
@@ -239,10 +254,12 @@ export const fetchConsumerGroupDetails = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.fetchConsumerGroupDetailsAction.request());
   dispatch(actions.fetchConsumerGroupDetailsAction.request());
   try {
   try {
-    const consumerGroupDetails = await apiClient.getConsumerGroup({
-      clusterName,
-      id: consumerGroupID,
-    });
+    const consumerGroupDetails = await consumerGroupsApiClient.getConsumerGroup(
+      {
+        clusterName,
+        id: consumerGroupID,
+      }
+    );
     dispatch(
     dispatch(
       actions.fetchConsumerGroupDetailsAction.success({
       actions.fetchConsumerGroupDetailsAction.success({
         consumerGroupID,
         consumerGroupID,
@@ -259,7 +276,7 @@ export const fetchSchemasByClusterName = (
 ): PromiseThunkResult<void> => async (dispatch) => {
 ): PromiseThunkResult<void> => async (dispatch) => {
   dispatch(actions.fetchSchemasByClusterNameAction.request());
   dispatch(actions.fetchSchemasByClusterNameAction.request());
   try {
   try {
-    const schemas = await apiClient.getSchemas({ clusterName });
+    const schemas = await schemasApiClient.getSchemas({ clusterName });
     dispatch(actions.fetchSchemasByClusterNameAction.success(schemas));
     dispatch(actions.fetchSchemasByClusterNameAction.success(schemas));
   } catch (e) {
   } catch (e) {
     dispatch(actions.fetchSchemasByClusterNameAction.failure());
     dispatch(actions.fetchSchemasByClusterNameAction.failure());
@@ -273,7 +290,7 @@ export const fetchSchemaVersions = (
   if (!subject) return;
   if (!subject) return;
   dispatch(actions.fetchSchemaVersionsAction.request());
   dispatch(actions.fetchSchemaVersionsAction.request());
   try {
   try {
-    const versions = await apiClient.getAllVersionsBySubject({
+    const versions = await schemasApiClient.getAllVersionsBySubject({
       clusterName,
       clusterName,
       subject,
       subject,
     });
     });
@@ -289,7 +306,7 @@ export const createSchema = (
 ): PromiseThunkResult => async (dispatch) => {
 ): PromiseThunkResult => async (dispatch) => {
   dispatch(actions.createSchemaAction.request());
   dispatch(actions.createSchemaAction.request());
   try {
   try {
-    const schema: SchemaSubject = await apiClient.createNewSchema({
+    const schema: SchemaSubject = await schemasApiClient.createNewSchema({
       clusterName,
       clusterName,
       newSchemaSubject,
       newSchemaSubject,
     });
     });