|
@@ -6,6 +6,7 @@ import static java.util.stream.Collectors.toMap;
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
|
import com.provectus.kafka.ui.exception.TopicMetadataException;
|
|
|
import com.provectus.kafka.ui.exception.TopicNotFoundException;
|
|
|
+import com.provectus.kafka.ui.exception.TopicRecreationException;
|
|
|
import com.provectus.kafka.ui.exception.ValidationException;
|
|
|
import com.provectus.kafka.ui.mapper.ClusterMapper;
|
|
|
import com.provectus.kafka.ui.model.Feature;
|
|
@@ -31,6 +32,7 @@ import com.provectus.kafka.ui.model.TopicUpdateDTO;
|
|
|
import com.provectus.kafka.ui.model.TopicsResponseDTO;
|
|
|
import com.provectus.kafka.ui.serde.DeserializationService;
|
|
|
import com.provectus.kafka.ui.util.JmxClusterUtil;
|
|
|
+import java.time.Duration;
|
|
|
import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Comparator;
|
|
@@ -39,8 +41,8 @@ import java.util.Map;
|
|
|
import java.util.Optional;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.function.Predicate;
|
|
|
+import java.util.stream.Collectors;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
-import lombok.Value;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.kafka.clients.admin.ConfigEntry;
|
|
|
import org.apache.kafka.clients.admin.NewPartitionReassignment;
|
|
@@ -49,8 +51,11 @@ import org.apache.kafka.clients.admin.OffsetSpec;
|
|
|
import org.apache.kafka.clients.admin.TopicDescription;
|
|
|
import org.apache.kafka.common.Node;
|
|
|
import org.apache.kafka.common.TopicPartition;
|
|
|
+import org.apache.kafka.common.errors.TopicExistsException;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import reactor.core.publisher.Mono;
|
|
|
+import reactor.util.retry.Retry;
|
|
|
|
|
|
@Service
|
|
|
@RequiredArgsConstructor
|
|
@@ -62,6 +67,10 @@ public class TopicsService {
|
|
|
private final ClusterMapper clusterMapper;
|
|
|
private final DeserializationService deserializationService;
|
|
|
private final MetricsCache metricsCache;
|
|
|
+ @Value("${topic.recreate.maxRetries:15}")
|
|
|
+ private int recreateMaxRetries;
|
|
|
+ @Value("${topic.recreate.delay.seconds:1}")
|
|
|
+ private int recreateDelayInSeconds;
|
|
|
|
|
|
public Mono<TopicsResponseDTO> getTopics(KafkaCluster cluster,
|
|
|
Optional<Integer> pageNum,
|
|
@@ -182,6 +191,30 @@ public class TopicsService {
|
|
|
.map(clusterMapper::toTopic);
|
|
|
}
|
|
|
|
|
|
+ public Mono<TopicDTO> recreateTopic(KafkaCluster cluster, String topicName) {
|
|
|
+ return loadTopic(cluster, topicName)
|
|
|
+ .flatMap(t -> deleteTopic(cluster, topicName)
|
|
|
+ .thenReturn(t).delayElement(Duration.ofSeconds(recreateDelayInSeconds))
|
|
|
+ .flatMap(topic -> adminClientService.get(cluster).flatMap(ac -> ac.createTopic(topic.getName(),
|
|
|
+ topic.getPartitionCount(),
|
|
|
+ (short) topic.getReplicationFactor(),
|
|
|
+ topic.getTopicConfigs()
|
|
|
+ .stream()
|
|
|
+ .collect(Collectors
|
|
|
+ .toMap(InternalTopicConfig::getName,
|
|
|
+ InternalTopicConfig::getValue)))
|
|
|
+ .thenReturn(topicName))
|
|
|
+ .retryWhen(Retry.fixedDelay(recreateMaxRetries,
|
|
|
+ Duration.ofSeconds(recreateDelayInSeconds))
|
|
|
+ .filter(throwable -> throwable instanceof TopicExistsException)
|
|
|
+ .onRetryExhaustedThrow((a, b) ->
|
|
|
+ new TopicRecreationException(topicName,
|
|
|
+ recreateMaxRetries * recreateDelayInSeconds)))
|
|
|
+ .flatMap(a -> loadTopic(cluster, topicName)).map(clusterMapper::toTopic)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
private Mono<InternalTopic> updateTopic(KafkaCluster cluster,
|
|
|
String topicName,
|
|
|
TopicUpdateDTO topicUpdate) {
|
|
@@ -395,12 +428,12 @@ public class TopicsService {
|
|
|
}
|
|
|
|
|
|
@VisibleForTesting
|
|
|
- @Value
|
|
|
+ @lombok.Value
|
|
|
static class Pagination {
|
|
|
ReactiveAdminClient adminClient;
|
|
|
MetricsCache.Metrics metrics;
|
|
|
|
|
|
- @Value
|
|
|
+ @lombok.Value
|
|
|
static class Page {
|
|
|
List<String> topics;
|
|
|
int totalPages;
|