From e749b54e1eb466a15cc1c26ff106a0f3be8473a4 Mon Sep 17 00:00:00 2001 From: Theodor Kvalsvik Lauritzen Date: Fri, 8 Nov 2024 12:44:47 +0100 Subject: [PATCH 1/2] refactor: Run vespa CLI from shell, to not hardcode the path to the binary --- .../clients/vscode/package.json | 3 ++- .../command/commandtypes/RunVespaQuery.java | 21 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/integration/schema-language-server/clients/vscode/package.json b/integration/schema-language-server/clients/vscode/package.json index 14f4265435e..ab32feee1c4 100644 --- a/integration/schema-language-server/clients/vscode/package.json +++ b/integration/schema-language-server/clients/vscode/package.json @@ -36,7 +36,8 @@ ], "extensions": [ ".sd", - ".profile" + ".profile", + ".yql" ], "configuration": "./language-configuration.json" } diff --git a/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java b/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java index b54f6ac310e..7eea4cb8c9b 100644 --- a/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java +++ b/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java @@ -56,6 +56,10 @@ public Object execute(EventExecuteCommandContext context) { QueryResult result = runVespaQuery(queryCommand, context.logger); if (!result.success()) { + if (result.result().toLowerCase().contains("command not found")) { + context.messageHandler.sendMessage(MessageType.Error, "Could not find vespa CLI. Make sure vespa CLI is installed and added to path. Download vespa CLI here: https://docs.vespa.ai/en/vespa-cli.html"); + return null; + } context.messageHandler.sendMessage(MessageType.Error, "Failed to run query:\n" + result.result()); return null; } @@ -103,24 +107,27 @@ private QueryResult runVespaQuery(String query, ClientLogger logger) { ProcessBuilder builder = new ProcessBuilder(); + String queryEscaped = query.replace("\"", "\\\""); + String vespaCommand = String.format("vespa query \"%s\"", queryEscaped); + if (isWindows) { - builder.command(String.format("cmd.exe /c %s", query)); // TODO: Fix this for window + builder.command("cmd.exe", "/c", vespaCommand); // TODO: Test this on windows } else { - builder.command("/usr/local/bin/vespa", "query", query); + builder.command("/bin/sh", "-c", vespaCommand); } try { Process process = builder.start(); - + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - + String line; StringBuilder output = new StringBuilder(); while ((line = reader.readLine()) != null) { output.append(line).append("\n"); } - + int exitCode = process.waitFor(); if (exitCode == 0) { @@ -134,7 +141,7 @@ private QueryResult runVespaQuery(String query, ClientLogger logger) { } return new QueryResult(false, error.toString()); - + } catch (InterruptedException e) { return new QueryResult(false, "Program interrupted"); } catch (IOException e) { @@ -142,5 +149,5 @@ private QueryResult runVespaQuery(String query, ClientLogger logger) { return new QueryResult(false, "IOException occurred."); } } - + } From 711765009eb8f3147134f85b84ee9b86a7467b5a Mon Sep 17 00:00:00 2001 From: Theodor Kvalsvik Lauritzen Date: Fri, 8 Nov 2024 12:59:34 +0100 Subject: [PATCH 2/2] refactor: Run yql queries async --- .../clients/vscode/package.json | 3 +- .../command/commandtypes/RunVespaQuery.java | 92 ++++++++++--------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/integration/schema-language-server/clients/vscode/package.json b/integration/schema-language-server/clients/vscode/package.json index ab32feee1c4..14f4265435e 100644 --- a/integration/schema-language-server/clients/vscode/package.json +++ b/integration/schema-language-server/clients/vscode/package.json @@ -36,8 +36,7 @@ ], "extensions": [ ".sd", - ".profile", - ".yql" + ".profile" ], "configuration": "./language-configuration.json" } diff --git a/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java b/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java index 7eea4cb8c9b..b66d446da78 100644 --- a/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java +++ b/integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/common/command/commandtypes/RunVespaQuery.java @@ -8,6 +8,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.List; +import java.util.concurrent.CompletableFuture; import org.apache.commons.math3.analysis.function.Pow; import org.eclipse.lsp4j.ApplyWorkspaceEditParams; @@ -53,35 +54,34 @@ public boolean setArguments(List arguments) { public Object execute(EventExecuteCommandContext context) { context.logger.info("Running Vespa query: " + queryCommand); - QueryResult result = runVespaQuery(queryCommand, context.logger); - - if (!result.success()) { - if (result.result().toLowerCase().contains("command not found")) { - context.messageHandler.sendMessage(MessageType.Error, "Could not find vespa CLI. Make sure vespa CLI is installed and added to path. Download vespa CLI here: https://docs.vespa.ai/en/vespa-cli.html"); - return null; + runVespaQuery(queryCommand, context.logger).thenAccept(result -> { + if (!result.success()) { + if (result.result().toLowerCase().contains("command not found")) { + context.messageHandler.sendMessage(MessageType.Error, "Could not find vespa CLI. Make sure vespa CLI is installed and added to path. Download vespa CLI here: https://docs.vespa.ai/en/vespa-cli.html"); + return; + } + context.messageHandler.sendMessage(MessageType.Error, "Failed to run query:\n" + result.result()); + return; } - context.messageHandler.sendMessage(MessageType.Error, "Failed to run query:\n" + result.result()); - return null; - } - String response = result.result(); + String response = result.result(); - String targetFileURI = getTargetFileURI(sourceFileURI); + String targetFileURI = getTargetFileURI(sourceFileURI); - CreateFile newFile = new CreateFile(targetFileURI); + CreateFile newFile = new CreateFile(targetFileURI); - TextEdit textEdit = new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), response); + TextEdit textEdit = new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), response); - WorkspaceEdit wsEdit = new WorkspaceEditBuilder() - .addResourceOperation(newFile) - .addTextEdit(targetFileURI, textEdit) - .build(); + WorkspaceEdit wsEdit = new WorkspaceEditBuilder() + .addResourceOperation(newFile) + .addTextEdit(targetFileURI, textEdit) + .build(); - context.messageHandler.applyEdit(new ApplyWorkspaceEditParams(wsEdit)).thenRun(() -> { - context.messageHandler.showDocument(targetFileURI); + context.messageHandler.applyEdit(new ApplyWorkspaceEditParams(wsEdit)).thenRun(() -> { + context.messageHandler.showDocument(targetFileURI); + }); }); - return null; } @@ -101,7 +101,7 @@ private static String getTargetFileURI(String sourceFileURI) { private record QueryResult(boolean success, String result) {}; - private QueryResult runVespaQuery(String query, ClientLogger logger) { + private CompletableFuture runVespaQuery(String query, ClientLogger logger) { boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows"); @@ -116,38 +116,40 @@ private QueryResult runVespaQuery(String query, ClientLogger logger) { builder.command("/bin/sh", "-c", vespaCommand); } - try { + return CompletableFuture.supplyAsync(() -> { + try { - Process process = builder.start(); + Process process = builder.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line; - StringBuilder output = new StringBuilder(); - while ((line = reader.readLine()) != null) { - output.append(line).append("\n"); - } + String line; + StringBuilder output = new StringBuilder(); + while ((line = reader.readLine()) != null) { + output.append(line).append("\n"); + } - int exitCode = process.waitFor(); + int exitCode = process.waitFor(); - if (exitCode == 0) { - return new QueryResult(true, output.toString()); - } + if (exitCode == 0) { + return new QueryResult(true, output.toString()); + } - BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); - StringBuilder error = new StringBuilder(); - while ((line = errorReader.readLine()) != null) { - error.append(line).append("\n"); - } + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + StringBuilder error = new StringBuilder(); + while ((line = errorReader.readLine()) != null) { + error.append(line).append("\n"); + } - return new QueryResult(false, error.toString()); + return new QueryResult(false, error.toString()); - } catch (InterruptedException e) { - return new QueryResult(false, "Program interrupted"); - } catch (IOException e) { - logger.error(e.getMessage()); - return new QueryResult(false, "IOException occurred."); - } + } catch (InterruptedException e) { + return new QueryResult(false, "Program interrupted"); + } catch (IOException e) { + logger.error(e.getMessage()); + return new QueryResult(false, "IOException occurred."); + } + }); } }