iliax 1 year ago
parent
commit
066157577d

+ 3 - 7
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/GraphsController.java

@@ -7,9 +7,9 @@ import com.provectus.kafka.ui.model.GraphDescriptionsDTO;
 import com.provectus.kafka.ui.model.GraphParameterDTO;
 import com.provectus.kafka.ui.model.PrometheusApiQueryResponseDTO;
 import com.provectus.kafka.ui.model.rbac.AccessContext;
+import com.provectus.kafka.ui.service.graphs.GraphDescription;
 import com.provectus.kafka.ui.service.graphs.GraphsService;
 import com.provectus.kafka.ui.service.audit.AuditService;
-import com.provectus.kafka.ui.service.graphs.GraphsStorage;
 import com.provectus.kafka.ui.service.rbac.AccessControlService;
 import java.time.Duration;
 import java.time.OffsetDateTime;
@@ -65,11 +65,7 @@ public class GraphsController extends AbstractController implements GraphsApi {
   @Override
   public Mono<ResponseEntity<GraphDescriptionsDTO>> getGraphsList(String clusterName,
                                                                   ServerWebExchange exchange) {
-    var graphs = graphsService.getAllGraphs();
-    var cluster = getCluster(clusterName);
-    if (cluster.getPrometheusStorageClient() == null) {
-      graphs = Stream.empty();
-    }
+    var graphs = graphsService.getGraphs(getCluster(clusterName));
     return Mono.just(
         ResponseEntity.ok(
             new GraphDescriptionsDTO().graphs(graphs.map(this::map).toList())
@@ -77,7 +73,7 @@ public class GraphsController extends AbstractController implements GraphsApi {
     );
   }
 
-  private GraphDescriptionDTO map(GraphsStorage.GraphDescription graph) {
+  private GraphDescriptionDTO map(GraphDescription graph) {
     return new GraphDescriptionDTO(graph.id())
         .defaultPeriod(Optional.ofNullable(graph.defaultInterval()).map(Duration::toString).orElse(null))
         .type(graph.isRange() ? GraphDescriptionDTO.TypeEnum.RANGE : GraphDescriptionDTO.TypeEnum.INSTANT)

+ 17 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/graphs/GraphDescription.java

@@ -0,0 +1,17 @@
+package com.provectus.kafka.ui.service.graphs;
+
+import java.time.Duration;
+import java.util.Set;
+import javax.annotation.Nullable;
+import lombok.Builder;
+
+@Builder
+public record GraphDescription(String id,
+                               @Nullable Duration defaultInterval, //null for instant queries, set for range
+                               String prometheusQuery,
+                               Set<String> params) {
+
+  public boolean isRange() {
+    return defaultInterval != null;
+  }
+}

+ 4 - 16
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/graphs/GraphsStorage.java → kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/graphs/GraphDescriptions.java

@@ -10,38 +10,26 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-import javax.annotation.Nullable;
-import lombok.Builder;
 import org.springframework.stereotype.Component;
 
 @Component
-public class GraphsStorage {
+class GraphDescriptions {
 
   private static final Duration DEFAULT_RANGE_DURATION = Duration.ofDays(7);
 
-  @Builder
-  public record GraphDescription(String id,
-                                 @Nullable Duration defaultInterval,
-                                 String prometheusQuery,
-                                 Set<String> params) {
-    public boolean isRange() {
-      return defaultInterval != null;
-    }
-  }
-
   private final Map<String, GraphDescription> graphsById;
 
-  GraphsStorage() {
+  GraphDescriptions() {
     validateGraphDescr(PREDEFINED_GRAPHS);
     this.graphsById = PREDEFINED_GRAPHS.stream()
         .collect(Collectors.toMap(GraphDescription::id, d -> d));
   }
 
-  Optional<GraphDescription> getDescription(String id) {
+  Optional<GraphDescription> getById(String id) {
     return Optional.ofNullable(graphsById.get(id));
   }
 
-  Stream<GraphDescription> getAll() {
+  Stream<GraphDescription> all() {
     return graphsById.values().stream();
   }
 

+ 10 - 9
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/graphs/GraphsService.java

@@ -4,7 +4,6 @@ import com.google.common.base.Preconditions;
 import com.provectus.kafka.ui.exception.NotFoundException;
 import com.provectus.kafka.ui.exception.ValidationException;
 import com.provectus.kafka.ui.model.KafkaCluster;
-import com.provectus.kafka.ui.service.graphs.GraphsStorage.GraphDescription;
 import com.provectus.kafka.ui.service.metrics.prometheus.PromQueryTemplate;
 import java.time.Duration;
 import java.time.Instant;
@@ -24,7 +23,7 @@ public class GraphsService {
 
   private static final int TARGET_MATRIX_DATA_POINTS = 200;
 
-  private final GraphsStorage graphsStorage;
+  private final GraphDescriptions graphDescriptions;
 
   public Mono<QueryResponse> getGraphData(KafkaCluster cluster,
                                           String id,
@@ -32,16 +31,16 @@ public class GraphsService {
                                           @Nullable Instant to,
                                           @Nullable Map<String, String> params) {
 
-    var graph = graphsStorage.getDescription(id)
+    var graph = graphDescriptions.getById(id)
         .orElseThrow(() -> new NotFoundException("No graph found with id = " + id));
 
     var promClient = cluster.getPrometheusStorageClient();
     if (promClient == null) {
       throw new ValidationException("Prometheus not configured for cluster");
     }
+    String preparedQuery = prepareQuery(graph, cluster.getName(), params);
     return cluster.getPrometheusStorageClient()
         .mono(client -> {
-          String preparedQuery = prepareQuery(graph, cluster.getName(), params);
           if (graph.isRange()) {
             return queryRange(client, preparedQuery, graph.defaultInterval(), from, to);
           }
@@ -75,8 +74,7 @@ public class GraphsService {
     if (intervalInSecs <= TARGET_MATRIX_DATA_POINTS) {
       return intervalInSecs + "s";
     }
-    int step = ((int) (((double) intervalInSecs) / 200));
-    System.out.println("Chosen step size " + step); //TODo
+    int step = ((int) (((double) intervalInSecs) / TARGET_MATRIX_DATA_POINTS));
     return step + "s";
   }
 
@@ -84,12 +82,15 @@ public class GraphsService {
     return c.query(preparedQuery, null, null);
   }
 
-  public static String prepareQuery(GraphDescription d, String clusterName, @Nullable Map<String, String> params) {
+  private String prepareQuery(GraphDescription d, String clusterName, @Nullable Map<String, String> params) {
     return new PromQueryTemplate(d).getQuery(clusterName, Optional.ofNullable(params).orElse(Map.of()));
   }
 
-  public Stream<GraphDescription> getAllGraphs() {
-    return graphsStorage.getAll();
+  public Stream<GraphDescription> getGraphs(KafkaCluster cluster) {
+    if (cluster.getPrometheusStorageClient() == null) {
+      return Stream.empty();
+    }
+    return graphDescriptions.all();
   }
 
 }

+ 11 - 17
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/metrics/prometheus/PromQueryLangGrammar.java

@@ -1,12 +1,10 @@
 package com.provectus.kafka.ui.service.metrics.prometheus;
 
-import com.provectus.kafka.ui.exception.ValidationException;
 import java.util.Optional;
-import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.BailErrorStrategy;
 import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.RecognitionException;
-import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
 import promql.PromQLLexer;
 import promql.PromQLParser;
 
@@ -17,27 +15,23 @@ class PromQueryLangGrammar {
     try {
       parseExpression(query);
       return Optional.empty();
-    } catch (ValidationException v) {
-      return Optional.of(v.getMessage());
+    } catch (ParseCancellationException e) {
+      //TODO: add more descriptive msg
+      return Optional.of("Syntax error");
     }
   }
 
   static PromQLParser.ExpressionContext parseExpression(String query) {
-    return parse(query).expression();
+    return createParser(query).expression();
   }
 
-  private static PromQLParser parse(String str) throws ValidationException {
+  private static PromQLParser createParser(String str) {
     PromQLLexer lexer = new PromQLLexer(CharStreams.fromString(str));
-    lexer.addErrorListener(new BaseErrorListener() {
-      @Override
-      public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
-                              int line, int charPositionInLine,
-                              String msg, RecognitionException e) {
-        throw new ValidationException("Invalid syntax: " + msg);
-      }
-    });
     CommonTokenStream tokenStream = new CommonTokenStream(lexer);
-    return new PromQLParser(tokenStream);
+    var parser = new PromQLParser(tokenStream);
+    parser.removeErrorListeners();
+    parser.setErrorHandler(new BailErrorStrategy());
+    return parser;
   }
 
 }

+ 4 - 3
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/metrics/prometheus/PromQueryTemplate.java

@@ -2,7 +2,7 @@ package com.provectus.kafka.ui.service.metrics.prometheus;
 
 import com.google.common.collect.Sets;
 import com.provectus.kafka.ui.exception.ValidationException;
-import com.provectus.kafka.ui.service.graphs.GraphsStorage;
+import com.provectus.kafka.ui.service.graphs.GraphDescription;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
@@ -14,7 +14,7 @@ public class PromQueryTemplate {
   private final String queryTemplate;
   private final Set<String> paramsNames;
 
-  public PromQueryTemplate(GraphsStorage.GraphDescription d) {
+  public PromQueryTemplate(GraphDescription d) {
     this(d.prometheusQuery(), d.params());
   }
 
@@ -35,8 +35,9 @@ public class PromQueryTemplate {
 
   public Optional<String> validateSyntax() {
     Map<String, String> fakeReplacements = new HashMap<>();
-    paramsNames.forEach(paramName -> fakeReplacements.put(paramName, "1"));
     fakeReplacements.put("cluster", "1");
+    paramsNames.forEach(paramName -> fakeReplacements.put(paramName, "1"));
+
     String prepared =  replaceParams(fakeReplacements);
     return PromQueryLangGrammar.validateExpression(prepared);
   }