|
@@ -1,22 +1,35 @@
|
|
|
package com.provectus.kafka.ui.service.ksql;
|
|
|
|
|
|
+import static ksql.KsqlGrammarParser.DefineVariableContext;
|
|
|
+import static ksql.KsqlGrammarParser.PrintTopicContext;
|
|
|
+import static ksql.KsqlGrammarParser.SingleStatementContext;
|
|
|
+import static ksql.KsqlGrammarParser.UndefineVariableContext;
|
|
|
+
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import com.fasterxml.jackson.databind.node.TextNode;
|
|
|
-import com.provectus.kafka.ui.exception.ValidationException;
|
|
|
import com.provectus.kafka.ui.model.KafkaCluster;
|
|
|
import com.provectus.kafka.ui.service.ksql.response.ResponseParser;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Optional;
|
|
|
+import java.util.Set;
|
|
|
import lombok.Builder;
|
|
|
import lombok.Value;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.http.MediaType;
|
|
|
import org.springframework.web.reactive.function.client.WebClient;
|
|
|
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
|
|
import reactor.core.publisher.Flux;
|
|
|
|
|
|
+@Slf4j
|
|
|
public class KsqlApiClient {
|
|
|
|
|
|
+ private static final Set<Class<?>> UNSUPPORTED_STMT_TYPES = Set.of(
|
|
|
+ PrintTopicContext.class,
|
|
|
+ DefineVariableContext.class,
|
|
|
+ UndefineVariableContext.class
|
|
|
+ );
|
|
|
+
|
|
|
@Builder
|
|
|
@Value
|
|
|
public static class KsqlResponseTable {
|
|
@@ -97,18 +110,40 @@ public class KsqlApiClient {
|
|
|
}
|
|
|
|
|
|
public Flux<KsqlResponseTable> execute(String ksql, Map<String, String> streamProperties) {
|
|
|
- var parsed = KsqlGrammar.parse(ksql);
|
|
|
- if (parsed.getStatements().size() > 1) {
|
|
|
- throw new ValidationException("Only single statement supported now");
|
|
|
+ var parsedStatements = KsqlGrammar.parse(ksql);
|
|
|
+ if (parsedStatements.isEmpty()) {
|
|
|
+ return errorTableFlux("Sql statement is invalid or unsupported");
|
|
|
+ }
|
|
|
+ var statements = parsedStatements.get().getStatements();
|
|
|
+ if (statements.size() > 1) {
|
|
|
+ return errorTableFlux("Only single statement supported now");
|
|
|
+ }
|
|
|
+ if (statements.size() == 0) {
|
|
|
+ return errorTableFlux("No valid ksql statement found");
|
|
|
}
|
|
|
- if (parsed.getStatements().isEmpty()) {
|
|
|
- throw new ValidationException("No valid ksql statement found");
|
|
|
+ if (isUnsupportedStatementType(statements.get(0))) {
|
|
|
+ return errorTableFlux("Unsupported statement type");
|
|
|
}
|
|
|
- if (KsqlGrammar.isSelect(parsed.getStatements().get(0))) {
|
|
|
- return executeSelect(ksql, streamProperties);
|
|
|
+ Flux<KsqlResponseTable> outputFlux;
|
|
|
+ if (KsqlGrammar.isSelect(statements.get(0))) {
|
|
|
+ outputFlux = executeSelect(ksql, streamProperties);
|
|
|
} else {
|
|
|
- return executeStatement(ksql, streamProperties);
|
|
|
+ outputFlux = executeStatement(ksql, streamProperties);
|
|
|
}
|
|
|
+ return outputFlux.onErrorResume(Exception.class,
|
|
|
+ e -> {
|
|
|
+ log.error("Unexpected error while execution ksql: {}", ksql, e);
|
|
|
+ return errorTableFlux("Unexpected error: " + e.getMessage());
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private Flux<KsqlResponseTable> errorTableFlux(String errorText) {
|
|
|
+ return Flux.just(ResponseParser.errorTableWithTextMsg(errorText));
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isUnsupportedStatementType(SingleStatementContext context) {
|
|
|
+ var ctxClass = context.statement().getClass();
|
|
|
+ return UNSUPPORTED_STMT_TYPES.contains(ctxClass);
|
|
|
}
|
|
|
|
|
|
}
|