You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2022/06/23 09:36:50 UTC
[ignite-3] branch main updated: IGNITE-17093 Map error codes for cli commands. #876
This is an automated email from the ASF dual-hosted git repository.
sk0x50 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 6a64a74ec IGNITE-17093 Map error codes for cli commands. #876
6a64a74ec is described below
commit 6a64a74ecee7981e1bb1d81b01fe3db724b91200
Author: Vadim Pakhnushev <86...@users.noreply.github.com>
AuthorDate: Thu Jun 23 12:36:03 2022 +0300
IGNITE-17093 Map error codes for cli commands. #876
Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
modules/cli/pom.xml | 6 +
.../configuration/ItShowConfigurationCallTest.java | 43 ----
.../commands/CliCommandTestIntegrationBase.java | 39 ++--
.../cli/commands/connect/ItConnectCommandTest.java | 8 +-
.../ignite/cli/commands/sql/ItSqlCommandTest.java | 2 -
.../ignite/cli/deprecated/ItConfigCommandTest.java | 8 +-
.../src/main/java/org/apache/ignite/cli/Main.java | 8 +-
.../call/configuration/ClusterConfigShowCall.java | 14 +-
.../configuration/ClusterConfigShowCallInput.java | 1 +
.../configuration/ClusterConfigUpdateCall.java | 22 +-
.../ClusterConfigUpdateCallInput.java | 4 +-
.../cli/call/configuration/NodeConfigShowCall.java | 14 +-
.../call/configuration/NodeConfigUpdateCall.java | 22 +-
.../ignite/cli/call/connect/ConnectCall.java | 12 +-
.../repl/executor => call/sql}/SqlQueryCall.java | 2 +-
.../apache/ignite/cli/call/status/StatusCall.java | 35 ++-
.../ignite/cli/call/status/StatusReplCall.java | 7 +-
.../apache/ignite/cli/commands/BaseCommand.java | 6 +-
.../ignite/cli/commands/TopLevelCliCommand.java | 5 -
.../cli/commands/TopLevelCliReplCommand.java | 4 +-
.../commands/cliconfig/CliConfigGetSubCommand.java | 7 +-
.../commands/cliconfig/CliConfigSetSubCommand.java | 7 +-
.../commands/cliconfig/CliConfigSubCommand.java | 7 +-
.../cluster/ClusterConfigShowReplSubCommand.java | 29 ++-
.../cluster/ClusterConfigShowSubCommand.java | 7 +-
.../cluster/ClusterConfigUpdateReplSubCommand.java | 4 +-
.../cluster/ClusterConfigUpdateSubCommand.java | 7 +-
.../node/NodeConfigShowReplSubCommand.java | 24 +--
.../node/NodeConfigShowSubCommand.java | 7 +-
.../node/NodeConfigUpdateReplSubCommand.java | 4 +-
.../node/NodeConfigUpdateSubCommand.java | 13 +-
.../cli/commands/connect/ConnectCommand.java | 15 +-
.../cli/commands/connect/DisconnectCommand.java | 7 +-
.../apache/ignite/cli/commands/sql/SqlCommand.java | 85 ++------
.../sql/{SqlCommand.java => SqlReplCommand.java} | 33 +--
.../ignite/cli/commands/status/StatusCommand.java | 16 +-
.../cli/commands/status/StatusReplCommand.java | 11 +-
.../cli/commands/topology/TopologyCommand.java | 13 +-
.../cli/commands/version/VersionCommand.java | 11 +-
.../cli/core/call/CallExecutionPipeline.java | 21 +-
.../ignite/cli/core/call/StatusCallInput.java | 1 +
.../cli/core/exception/ExceptionHandler.java | 8 +-
.../cli/core/exception/ExceptionHandlers.java | 13 +-
...tionHandler.java => IgniteCliApiException.java} | 35 +--
.../handler/CommandExecutionExceptionHandler.java | 41 ----
.../handler/ConnectCommandExceptionHandler.java | 37 ----
.../exception/handler/ConnectExceptionHandler.java | 37 ----
.../handler/DefaultExceptionHandlers.java | 5 +-
.../handler/EndOfFileExceptionHandler.java | 3 +-
.../handler/IgniteCliApiExceptionHandler.java | 65 ++++++
.../handler/IgniteCliExceptionHandler.java | 3 +-
.../handler/IgniteClientExceptionHandler.java | 3 +-
.../handler/PicocliExecutionExceptionHandler.java | 3 +-
.../exception/handler/SqlExceptionHandler.java | 3 +-
.../exception/handler/TimeoutExceptionHandler.java | 3 +-
.../handler/UnknownCommandExceptionHandler.java | 4 +-
.../handler/UserInterruptExceptionHandler.java | 3 +-
.../builtins/cluster/ClusterApiClient.java | 3 +-
.../spec/BootstrapIgniteCommandSpec.java | 7 +-
.../cli/deprecated/spec/ClusterCommandSpec.java | 6 +-
.../deprecated/spec/ClusterReplCommandSpec.java | 2 +-
.../cli/deprecated/spec/NodeCommandSpec.java | 21 +-
.../org/apache/ignite/cli/sql/SqlSchemaLoader.java | 4 +-
.../ignite/cli/commands/CliCommandTestBase.java | 86 +++++++-
.../cli/commands/UrlOptionsNegativeTest.java | 235 +++++++++++++++++++++
.../cliconfig/CliConfigGetSubCommandTest.java | 47 +++--
.../cliconfig/CliConfigSetSubCommandTest.java | 53 ++---
.../cliconfig/CliConfigSubCommandTest.java | 19 +-
.../configuration/ShowConfigSubCommandTest.java | 48 -----
.../ignite/cli/commands/sql/SqlCommandTest.java | 56 +++++
70 files changed, 779 insertions(+), 665 deletions(-)
diff --git a/modules/cli/pom.xml b/modules/cli/pom.xml
index 07d258972..e95d9fef3 100644
--- a/modules/cli/pom.xml
+++ b/modules/cli/pom.xml
@@ -214,6 +214,12 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/call/configuration/ItShowConfigurationCallTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/call/configuration/ItShowConfigurationCallTest.java
index aa66ccd0b..786fd8dd5 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/call/configuration/ItShowConfigurationCallTest.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/call/configuration/ItShowConfigurationCallTest.java
@@ -19,14 +19,9 @@ package org.apache.ignite.cli.call.configuration;
import static org.assertj.core.api.Assertions.assertThat;
-import com.google.common.primitives.Chars;
import jakarta.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.ignite.cli.call.CallIntegrationTestBase;
-import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
-import org.apache.ignite.cli.core.exception.handler.CommandExecutionExceptionHandler;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -110,42 +105,4 @@ class ItShowConfigurationCallTest extends CallIntegrationTestBase {
// And
assertThat(output.body()).isEqualTo("5000");
}
-
- @Test
- @DisplayName("Should display error when wrong port is given")
- public void incorrectPortTest() {
- var input = NodeConfigShowCallInput.builder()
- .nodeUrl(NODE_URL + "incorrect")
- .build();
- List<Character> list = new ArrayList<>();
-
- CallExecutionPipeline.builder(nodeConfigShowCall)
- .inputProvider(() -> input)
- .exceptionHandler(new CommandExecutionExceptionHandler())
- .errOutput(output(list))
- .build()
- .runPipeline();
-
- assertThat(new String(Chars.toArray(list)))
- .contains("Invalid URL port: \"10300incorrect");
- }
-
- @Test
- @DisplayName("Should display error when wrong url is given")
- public void incorrectSchemeTest() {
- var input = NodeConfigShowCallInput.builder()
- .nodeUrl("incorrect" + NODE_URL)
- .build();
- List<Character> list = new ArrayList<>();
-
- CallExecutionPipeline.builder(nodeConfigShowCall)
- .inputProvider(() -> input)
- .exceptionHandler(new CommandExecutionExceptionHandler())
- .errOutput(output(list))
- .build()
- .runPipeline();
-
- assertThat(new String(Chars.toArray(list)))
- .contains("Expected URL scheme 'http' or 'https' but was 'incorrecthttp'");
- }
}
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestIntegrationBase.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestIntegrationBase.java
index b59ce489b..363787cfd 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestIntegrationBase.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestIntegrationBase.java
@@ -25,7 +25,6 @@ import jakarta.inject.Inject;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.ignite.cli.IntegrationTestBase;
-import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import picocli.CommandLine;
@@ -38,26 +37,30 @@ public class CliCommandTestIntegrationBase extends IntegrationTestBase {
protected static final String JDBC_URL = "jdbc:ignite:thin://127.0.0.1:10800";
@Inject
- protected ApplicationContext applicationContext;
+ private ApplicationContext context;
private CommandLine cmd;
-
private StringWriter sout;
-
private StringWriter serr;
-
private int exitCode = Integer.MIN_VALUE;
- protected void setupCmd(MicronautFactory factory) {
- cmd = new CommandLine(getCommandClass(), factory);
+ /**
+ * Invokes before the test will start.
+ *
+ * @param testInfo Test information object.
+ * @throws Exception If failed.
+ */
+ @BeforeEach
+ public void setUp(TestInfo testInfo) throws Exception {
+ super.setUp(testInfo);
+ cmd = new CommandLine(getCommandClass(), new MicronautFactory(context));
sout = new StringWriter();
serr = new StringWriter();
cmd.setOut(new PrintWriter(sout));
cmd.setErr(new PrintWriter(serr));
}
- @NotNull
- protected Class getCommandClass() {
+ protected Class<?> getCommandClass() {
return TopLevelCliCommand.class;
}
@@ -66,10 +69,9 @@ public class CliCommandTestIntegrationBase extends IntegrationTestBase {
}
protected void assertExitCodeIs(int expectedExitCode) {
- //TODO: https://issues.apache.org/jira/browse/IGNITE-17093
- /*assertThat(exitCode)
+ assertThat(exitCode)
.as("Expected exit code to be: " + expectedExitCode + " but was " + exitCode)
- .isEqualTo(expectedExitCode);*/
+ .isEqualTo(expectedExitCode);
}
protected void assertExitCodeIsZero() {
@@ -117,17 +119,4 @@ public class CliCommandTestIntegrationBase extends IntegrationTestBase {
.as("Expected command error output to be equal to: " + expectedErrOutput)
.isEqualTo(expectedErrOutput);
}
-
- /**
- * Invokes before the test will start.
- *
- * @param testInfo Test information object.
- * @throws Exception If failed.
- */
- @BeforeEach
- public void setUp(TestInfo testInfo) throws Exception {
- super.setUp(testInfo);
- setupCmd(new MicronautFactory(applicationContext));
- }
}
-
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/connect/ItConnectCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/connect/ItConnectCommandTest.java
index ef82683ee..2b10db076 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/connect/ItConnectCommandTest.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/connect/ItConnectCommandTest.java
@@ -24,7 +24,6 @@ import jakarta.inject.Inject;
import org.apache.ignite.cli.commands.CliCommandTestIntegrationBase;
import org.apache.ignite.cli.commands.TopLevelCliReplCommand;
import org.apache.ignite.cli.core.repl.prompt.PromptProvider;
-import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import picocli.CommandLine.Help.Ansi;
@@ -34,7 +33,7 @@ class ItConnectCommandTest extends CliCommandTestIntegrationBase {
PromptProvider promptProvider;
@Override
- protected @NotNull Class<?> getCommandClass() {
+ protected Class<?> getCommandClass() {
return TopLevelCliReplCommand.class;
}
@@ -50,7 +49,6 @@ class ItConnectCommandTest extends CliCommandTestIntegrationBase {
// Then
assertAll(
- this::assertExitCodeIsZero,
this::assertErrOutputIsEmpty,
() -> assertOutputContains("Connected to http://localhost:10300")
);
@@ -67,7 +65,6 @@ class ItConnectCommandTest extends CliCommandTestIntegrationBase {
// Then
assertAll(
- this::assertExitCodeIsZero,
this::assertErrOutputIsEmpty,
() -> assertOutputContains("Connected to http://localhost:10301")
);
@@ -81,7 +78,7 @@ class ItConnectCommandTest extends CliCommandTestIntegrationBase {
// Then
assertAll(
- () -> assertErrOutputIs("Can not connect to http://localhost:11111" + System.lineSeparator())
+ () -> assertErrOutputIs("Could not connect to URL: http://localhost:11111" + System.lineSeparator())
);
// And prompt is
String prompt = Ansi.OFF.string(promptProvider.getPrompt());
@@ -101,7 +98,6 @@ class ItConnectCommandTest extends CliCommandTestIntegrationBase {
execute("disconnect");
// Then
assertAll(
- this::assertExitCodeIsZero,
this::assertErrOutputIsEmpty,
() -> assertOutputContains("Disconnected from http://localhost:10300")
);
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
index 31dd7b486..68933cbe3 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/sql/ItSqlCommandTest.java
@@ -63,7 +63,6 @@ class ItSqlCommandTest extends CliCommandTestIntegrationBase {
assertAll(
() -> assertExitCodeIs(1),
this::assertOutputIsEmpty,
- this::assertErrOutputIsNotEmpty,
// TODO: https://issues.apache.org/jira/browse/IGNITE-17090
() -> assertErrOutputIs(CLIENT_CONNECTION_FAILED_MESSAGE + System.lineSeparator())
);
@@ -77,7 +76,6 @@ class ItSqlCommandTest extends CliCommandTestIntegrationBase {
assertAll(
() -> assertExitCodeIs(1),
this::assertOutputIsEmpty,
- this::assertErrOutputIsNotEmpty,
// TODO: https://issues.apache.org/jira/browse/IGNITE-17090
() -> assertErrOutputIs("SQL query parsing error: Sql query execution failed." + System.lineSeparator())
);
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItConfigCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItConfigCommandTest.java
index 52dfc8742..2bbd71bd3 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItConfigCommandTest.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItConfigCommandTest.java
@@ -123,10 +123,10 @@ public class ItConfigCommandTest extends AbstractCliIntegrationTest {
"network.foo=\"bar\""
);
- //assertEquals(1, exitCode); // TODO
+ assertEquals(1, exitCode);
assertThat(
err.toString(UTF_8),
- both(startsWith("Command node config update failed with reason: Got error while updating the node configuration."))
+ both(startsWith("An error occurred"))
.and(containsString("'network' configuration doesn't have the 'foo' sub-configuration"))
);
@@ -141,10 +141,10 @@ public class ItConfigCommandTest extends AbstractCliIntegrationTest {
"network.shutdownQuietPeriod=asd"
);
- //assertEquals(1, exitCode); // TODO
+ assertEquals(1, exitCode);
assertThat(
err.toString(UTF_8),
- both(containsString("Command node config update failed with reason: Got error while updating the node configuration."))
+ both(containsString("An error occurred"))
.and(containsString("'long' is expected as a type for the 'network.shutdownQuietPeriod' configuration value"))
);
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/Main.java b/modules/cli/src/main/java/org/apache/ignite/cli/Main.java
index ca443970d..eeb0f37c9 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/Main.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/Main.java
@@ -54,11 +54,12 @@ public class Main {
public static void main(String[] args) {
initJavaLoggerProps();
+ int exitCode = 0;
try (MicronautFactory micronautFactory = new MicronautFactory()) {
AnsiConsole.systemInstall();
if (args.length != 0 || !isatty()) { // do not enter REPL if input or output is redirected
try {
- executeCommand(args, micronautFactory);
+ exitCode = executeCommand(args, micronautFactory);
} catch (Exception e) {
System.err.println("Error occurred during command execution");
}
@@ -72,6 +73,7 @@ public class Main {
} finally {
AnsiConsole.systemUninstall();
}
+ System.exit(exitCode);
}
private static boolean isatty() {
@@ -108,12 +110,12 @@ public class Main {
.build());
}
- private static void executeCommand(String[] args, MicronautFactory micronautFactory) throws Exception {
+ private static int executeCommand(String[] args, MicronautFactory micronautFactory) throws Exception {
CommandLine cmd = new CommandLine(TopLevelCliCommand.class, micronautFactory);
cmd.setExecutionExceptionHandler(new PicocliExecutionExceptionHandler());
Config config = micronautFactory.create(Config.class);
cmd.setDefaultValueProvider(new CommandLine.PropertiesDefaultProvider(config.getProperties()));
- cmd.execute(args);
+ return cmd.execute(args);
}
private static final String[] BANNER = new String[]{
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCall.java
index 28cc526c5..55413acee 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCall.java
@@ -20,7 +20,7 @@ package org.apache.ignite.cli.call.configuration;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.rest.client.api.ClusterConfigurationApi;
import org.apache.ignite.rest.client.invoker.ApiClient;
import org.apache.ignite.rest.client.invoker.ApiException;
@@ -34,15 +34,13 @@ public class ClusterConfigShowCall implements Call<ClusterConfigShowCallInput, S
/** {@inheritDoc} */
@Override
- public DefaultCallOutput<String> execute(ClusterConfigShowCallInput clusterConfigShowCallInput) {
- ClusterConfigurationApi client = createApiClient(clusterConfigShowCallInput);
+ public DefaultCallOutput<String> execute(ClusterConfigShowCallInput input) {
+ ClusterConfigurationApi client = createApiClient(input);
try {
- return DefaultCallOutput.success(readClusterConfig(client, clusterConfigShowCallInput));
- } catch (ApiException e) {
- return DefaultCallOutput.failure(e);
- } catch (IllegalArgumentException e) {
- return DefaultCallOutput.failure(new CommandExecutionException("cluster config show", e.getMessage()));
+ return DefaultCallOutput.success(readClusterConfig(client, input));
+ } catch (ApiException | IllegalArgumentException e) {
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, input.getClusterUrl()));
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCallInput.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCallInput.java
index 87ba85633..687d8d97d 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCallInput.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigShowCallInput.java
@@ -68,6 +68,7 @@ public class ClusterConfigShowCallInput implements CallInput {
*/
public static class ShowConfigurationCallInputBuilder {
private String selector;
+
private String clusterUrl;
public ShowConfigurationCallInputBuilder selector(String selector) {
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCall.java
index 6a19a6523..52770eb25 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCall.java
@@ -20,12 +20,11 @@ package org.apache.ignite.cli.call.configuration;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.rest.client.api.ClusterConfigurationApi;
import org.apache.ignite.rest.client.invoker.ApiClient;
import org.apache.ignite.rest.client.invoker.ApiException;
import org.apache.ignite.rest.client.invoker.Configuration;
-import org.jetbrains.annotations.NotNull;
/**
* Updates cluster configuration.
@@ -34,21 +33,13 @@ import org.jetbrains.annotations.NotNull;
public class ClusterConfigUpdateCall implements Call<ClusterConfigUpdateCallInput, String> {
/** {@inheritDoc} */
@Override
- public DefaultCallOutput<String> execute(ClusterConfigUpdateCallInput clusterConfigUpdateCallInput) {
- ClusterConfigurationApi client = createApiClient(clusterConfigUpdateCallInput);
+ public DefaultCallOutput<String> execute(ClusterConfigUpdateCallInput input) {
+ ClusterConfigurationApi client = createApiClient(input);
try {
- return updateClusterConfig(client, clusterConfigUpdateCallInput);
- } catch (ApiException e) {
- if (e.getCode() == 400) {
- return DefaultCallOutput.failure(
- new CommandExecutionException(
- "cluster config update",
- "Got error while updating the cluster configuration. " + System.lineSeparator()
- + "Code: " + e.getCode() + ", response: " + e.getResponseBody()
- ));
- }
- return DefaultCallOutput.failure(new CommandExecutionException("cluster config update", "Ignite api return " + e.getCode()));
+ return updateClusterConfig(client, input);
+ } catch (ApiException | IllegalArgumentException e) {
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, input.getClusterUrl()));
}
}
@@ -58,7 +49,6 @@ public class ClusterConfigUpdateCall implements Call<ClusterConfigUpdateCallInpu
return DefaultCallOutput.success("Cluster configuration was updated successfully.");
}
- @NotNull
private ClusterConfigurationApi createApiClient(ClusterConfigUpdateCallInput input) {
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath(input.getClusterUrl());
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCallInput.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCallInput.java
index d0250cd53..2ebbe7efa 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCallInput.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/ClusterConfigUpdateCallInput.java
@@ -20,7 +20,7 @@ package org.apache.ignite.cli.call.configuration;
import org.apache.ignite.cli.core.call.CallInput;
/**
- * Input for {@link NodeConfigUpdateCall}.
+ * Input for {@link ClusterConfigUpdateCall}.
*/
public class ClusterConfigUpdateCallInput implements CallInput {
/**
@@ -59,7 +59,7 @@ public class ClusterConfigUpdateCallInput implements CallInput {
/**
* Get cluster URL.
*
- * @return Cluster url.
+ * @return Cluster URL.
*/
public String getClusterUrl() {
return clusterUrl;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigShowCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigShowCall.java
index b3f7e8fa8..a7b2ec846 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigShowCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigShowCall.java
@@ -20,7 +20,7 @@ package org.apache.ignite.cli.call.configuration;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.rest.client.api.NodeConfigurationApi;
import org.apache.ignite.rest.client.invoker.ApiClient;
import org.apache.ignite.rest.client.invoker.ApiException;
@@ -34,15 +34,13 @@ public class NodeConfigShowCall implements Call<NodeConfigShowCallInput, String>
/** {@inheritDoc} */
@Override
- public DefaultCallOutput<String> execute(NodeConfigShowCallInput readConfigurationInput) {
- NodeConfigurationApi client = createApiClient(readConfigurationInput);
+ public DefaultCallOutput<String> execute(NodeConfigShowCallInput input) {
+ NodeConfigurationApi client = createApiClient(input);
try {
- return DefaultCallOutput.success(readNodeConfig(client, readConfigurationInput));
- } catch (ApiException e) {
- return DefaultCallOutput.failure(e);
- } catch (IllegalArgumentException e) {
- return DefaultCallOutput.failure(new CommandExecutionException("node config show", e.getMessage()));
+ return DefaultCallOutput.success(readNodeConfig(client, input));
+ } catch (ApiException | IllegalArgumentException e) {
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, input.getNodeUrl()));
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigUpdateCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigUpdateCall.java
index c073e5310..382441155 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigUpdateCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/configuration/NodeConfigUpdateCall.java
@@ -20,12 +20,11 @@ package org.apache.ignite.cli.call.configuration;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.rest.client.api.NodeConfigurationApi;
import org.apache.ignite.rest.client.invoker.ApiClient;
import org.apache.ignite.rest.client.invoker.ApiException;
import org.apache.ignite.rest.client.invoker.Configuration;
-import org.jetbrains.annotations.NotNull;
/**
* Updates configuration for node.
@@ -34,21 +33,13 @@ import org.jetbrains.annotations.NotNull;
public class NodeConfigUpdateCall implements Call<NodeConfigUpdateCallInput, String> {
/** {@inheritDoc} */
@Override
- public DefaultCallOutput<String> execute(NodeConfigUpdateCallInput nodeConfigUpdateCallInput) {
- NodeConfigurationApi client = createApiClient(nodeConfigUpdateCallInput);
+ public DefaultCallOutput<String> execute(NodeConfigUpdateCallInput input) {
+ NodeConfigurationApi client = createApiClient(input);
try {
- return updateNodeConfig(client, nodeConfigUpdateCallInput);
- } catch (ApiException e) {
- if (e.getCode() == 400) {
- return DefaultCallOutput.failure(
- new CommandExecutionException(
- "node config update",
- "Got error while updating the node configuration. " + System.lineSeparator()
- + "Code: " + e.getCode() + ", response: " + e.getResponseBody()
- ));
- }
- return DefaultCallOutput.failure(new CommandExecutionException("node config update", "Ignite api return " + e.getCode()));
+ return updateNodeConfig(client, input);
+ } catch (ApiException | IllegalArgumentException e) {
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, input.getNodeUrl()));
}
}
@@ -58,7 +49,6 @@ public class NodeConfigUpdateCall implements Call<NodeConfigUpdateCallInput, Str
return DefaultCallOutput.success("Node configuration was updated successfully.");
}
- @NotNull
private NodeConfigurationApi createApiClient(NodeConfigUpdateCallInput input) {
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath(input.getNodeUrl());
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/connect/ConnectCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/connect/ConnectCall.java
index 270fb5cc8..67c099f3f 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/connect/ConnectCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/connect/ConnectCall.java
@@ -19,20 +19,18 @@ package org.apache.ignite.cli.call.connect;
import com.google.gson.Gson;
import jakarta.inject.Singleton;
-import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.CallOutput;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
-import org.apache.ignite.cli.core.exception.ConnectCommandException;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.cli.core.repl.Session;
import org.apache.ignite.cli.core.repl.config.RootConfig;
import org.apache.ignite.rest.client.api.NodeConfigurationApi;
import org.apache.ignite.rest.client.invoker.ApiClient;
import org.apache.ignite.rest.client.invoker.ApiException;
import org.apache.ignite.rest.client.invoker.Configuration;
-import org.jetbrains.annotations.NotNull;
/**
@@ -54,12 +52,9 @@ public class ConnectCall implements Call<ConnectCallInput, String> {
try {
String configuration = api.getNodeConfiguration();
setJdbcUrl(configuration, nodeUrl);
- } catch (ApiException e) {
+ } catch (ApiException | IllegalArgumentException e) {
session.setConnectedToNode(false);
- if (e.getCause() instanceof ConnectException) {
- return DefaultCallOutput.failure(new ConnectCommandException("Can not connect to " + input.getNodeUrl()));
- }
- return DefaultCallOutput.failure(e);
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, nodeUrl));
}
session.setNodeUrl(nodeUrl);
@@ -67,7 +62,6 @@ public class ConnectCall implements Call<ConnectCallInput, String> {
return DefaultCallOutput.success("Connected to " + nodeUrl);
}
- @NotNull
private NodeConfigurationApi createApiClient(ConnectCallInput input) {
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath(input.getNodeUrl());
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/SqlQueryCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/sql/SqlQueryCall.java
similarity index 97%
rename from modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/SqlQueryCall.java
rename to modules/cli/src/main/java/org/apache/ignite/cli/call/sql/SqlQueryCall.java
index 7c19262f1..8c1ea8926 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/SqlQueryCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/sql/SqlQueryCall.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.cli.core.repl.executor;
+package org.apache.ignite.cli.call.sql;
import java.sql.SQLException;
import org.apache.ignite.cli.core.call.Call;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusCall.java
index 294d249f9..55a860af4 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusCall.java
@@ -18,12 +18,11 @@
package org.apache.ignite.cli.call.status;
import jakarta.inject.Singleton;
-import java.net.ConnectException;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.CallOutput;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
import org.apache.ignite.cli.core.call.StatusCallInput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.cli.deprecated.CliPathsConfigLoader;
import org.apache.ignite.cli.deprecated.IgnitePaths;
import org.apache.ignite.cli.deprecated.builtins.node.NodeManager;
@@ -37,7 +36,6 @@ import org.apache.ignite.rest.client.invoker.Configuration;
* Call to get cluster status.
*/
@Singleton
-//TODO: https://issues.apache.org/jira/browse/IGNITE-17093
public class StatusCall implements Call<StatusCallInput, Status> {
private final NodeManager nodeManager;
@@ -55,32 +53,27 @@ public class StatusCall implements Call<StatusCallInput, Status> {
@Override
public CallOutput<Status> execute(StatusCallInput input) {
IgnitePaths paths = cliPathsCfgLdr.loadIgnitePathsOrThrowError();
- String connected = null;
try {
- connected = createNodeApi(input).getNodeConfiguration();
- } catch (ApiException e) {
- if (e.getCause() instanceof ConnectException) {
- return DefaultCallOutput.failure(new CommandExecutionException("status", "cannot connect to " + input.getClusterUrl()));
- } else {
- return DefaultCallOutput.failure(e);
- }
+ String connected = createNodeApi(input).getNodeConfiguration();
+ return DefaultCallOutput.success(
+ Status.builder()
+ .connected(connected != null)
+ .connectedNodeUrl(input.getClusterUrl())
+ .initialized(connected != null && canReadClusterConfig(input))
+ .nodeCount(nodeManager.getRunningNodes(paths.logDir, paths.cliPidsDir()).size())
+ .build()
+ );
+ } catch (ApiException | IllegalArgumentException e) {
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, input.getClusterUrl()));
}
- return DefaultCallOutput.success(
- Status.builder()
- .connected(connected != null)
- .connectedNodeUrl(input.getClusterUrl())
- .initialized(connected != null && canReadClusterConfig(input))
- .nodeCount(nodeManager.getRunningNodes(paths.logDir, paths.cliPidsDir()).size())
- .build()
- );
}
private boolean canReadClusterConfig(StatusCallInput input) {
- var clusterApi = createClusterApi(input);
+ ClusterConfigurationApi clusterApi = createClusterApi(input);
try {
clusterApi.getClusterConfiguration();
return true;
- } catch (ApiException e) {
+ } catch (ApiException | IllegalArgumentException e) {
return false;
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusReplCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusReplCall.java
index a7c8babcf..14d325246 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusReplCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/status/StatusReplCall.java
@@ -30,13 +30,11 @@ import org.apache.ignite.rest.client.api.ClusterConfigurationApi;
import org.apache.ignite.rest.client.invoker.ApiClient;
import org.apache.ignite.rest.client.invoker.ApiException;
import org.apache.ignite.rest.client.invoker.Configuration;
-import org.jetbrains.annotations.NotNull;
/**
* Call to get cluster status.
*/
@Singleton
-//TODO: https://issues.apache.org/jira/browse/IGNITE-17093
public class StatusReplCall implements Call<EmptyCallInput, Status> {
private final NodeManager nodeManager;
@@ -68,16 +66,15 @@ public class StatusReplCall implements Call<EmptyCallInput, Status> {
}
private boolean canReadClusterConfig() {
- var clusterApi = createApiClient();
+ ClusterConfigurationApi clusterApi = createApiClient();
try {
clusterApi.getClusterConfiguration();
return true;
- } catch (ApiException e) {
+ } catch (ApiException | IllegalArgumentException e) {
return false;
}
}
- @NotNull
private ClusterConfigurationApi createApiClient() {
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath(session.getNodeUrl());
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/BaseCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/BaseCommand.java
index 46f8b4b26..8e05a2dc5 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/BaseCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/BaseCommand.java
@@ -24,15 +24,11 @@ import picocli.CommandLine.Spec;
/**
* Base class for commands.
*/
-public abstract class BaseCommand implements Runnable {
+public abstract class BaseCommand {
/** Help option specification. */
@Option(names = {"-h", "--help"}, usageHelp = true, description = "Show this help message and exit.")
protected boolean usageHelpRequested;
@Spec
protected CommandSpec spec;
-
- @Override
- public void run() {
- }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java
index 040523bee..981ed9ced 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java
@@ -52,9 +52,4 @@ public class TopLevelCliCommand extends BaseCommand {
@SuppressWarnings("PMD.UnusedPrivateField")
@Option(names = {"--version"}, versionHelp = true, description = "Print version information and exit")
private boolean versionRequested;
-
- @Override
- public void run() {
-
- }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java
index 94638253e..db4766553 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java
@@ -23,7 +23,7 @@ import org.apache.ignite.cli.commands.configuration.cluster.ClusterReplCommand;
import org.apache.ignite.cli.commands.configuration.node.NodeReplCommand;
import org.apache.ignite.cli.commands.connect.ConnectCommand;
import org.apache.ignite.cli.commands.connect.DisconnectCommand;
-import org.apache.ignite.cli.commands.sql.SqlCommand;
+import org.apache.ignite.cli.commands.sql.SqlReplCommand;
import org.apache.ignite.cli.commands.status.StatusReplCommand;
import org.apache.ignite.cli.commands.version.VersionCommand;
import org.apache.ignite.cli.deprecated.spec.BootstrapIgniteCommandSpec;
@@ -36,7 +36,7 @@ import picocli.shell.jline3.PicocliCommands;
@CommandLine.Command(name = "",
footer = {"", "Press Ctrl-D to exit."},
subcommands = {
- SqlCommand.class,
+ SqlReplCommand.class,
PicocliCommands.ClearScreen.class,
CommandLine.HelpCommand.class,
VersionCommand.class,
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommand.java
index 7f33bfdd5..9ad7a23b2 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommand.java
@@ -18,6 +18,7 @@
package org.apache.ignite.cli.commands.cliconfig;
import jakarta.inject.Inject;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.cliconfig.CliConfigGetCall;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
@@ -29,7 +30,7 @@ import picocli.CommandLine.Parameters;
* Command to get CLI configuration parameters.
*/
@Command(name = "get")
-public class CliConfigGetSubCommand extends BaseCommand {
+public class CliConfigGetSubCommand extends BaseCommand implements Callable<Integer> {
@Parameters
private String key;
@@ -37,8 +38,8 @@ public class CliConfigGetSubCommand extends BaseCommand {
private CliConfigGetCall call;
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(() -> new StringCallInput(key))
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommand.java
index 137a41fd2..f78b82d78 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommand.java
@@ -19,6 +19,7 @@ package org.apache.ignite.cli.commands.cliconfig;
import jakarta.inject.Inject;
import java.util.Map;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.cliconfig.CliConfigSetCall;
import org.apache.ignite.cli.call.cliconfig.CliConfigSetCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
@@ -30,7 +31,7 @@ import picocli.CommandLine.Parameters;
* Command to set CLI configuration parameters.
*/
@Command(name = "set")
-public class CliConfigSetSubCommand extends BaseCommand {
+public class CliConfigSetSubCommand extends BaseCommand implements Callable<Integer> {
@Parameters(arity = "1..*")
private Map<String, String> parameters;
@@ -38,8 +39,8 @@ public class CliConfigSetSubCommand extends BaseCommand {
private CliConfigSetCall call;
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(() -> new CliConfigSetCallInput(parameters))
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommand.java
index 095518504..a622631db 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommand.java
@@ -19,6 +19,7 @@ package org.apache.ignite.cli.commands.cliconfig;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.cliconfig.CliConfigCall;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.commands.decorators.ConfigDecorator;
@@ -34,14 +35,14 @@ import picocli.CommandLine.Command;
CliConfigSetSubCommand.class
})
@Singleton
-public class CliConfigSubCommand extends BaseCommand {
+public class CliConfigSubCommand extends BaseCommand implements Callable<Integer> {
@Inject
private CliConfigCall call;
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(EmptyCallInput::new)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowReplSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowReplSubCommand.java
index 65fd49b95..a0cd050f4 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowReplSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowReplSubCommand.java
@@ -23,8 +23,9 @@ import org.apache.ignite.cli.call.configuration.ClusterConfigShowCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.commands.decorators.JsonDecorator;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
-import org.apache.ignite.cli.core.exception.ExceptionHandler;
import org.apache.ignite.cli.core.exception.ExceptionWriter;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
+import org.apache.ignite.cli.core.exception.handler.IgniteCliApiExceptionHandler;
import org.apache.ignite.cli.core.repl.Session;
import org.apache.ignite.rest.client.invoker.ApiException;
import picocli.CommandLine.Command;
@@ -35,7 +36,7 @@ import picocli.CommandLine.Option;
*/
@Command(name = "show",
description = "Shows cluster configuration.")
-public class ClusterConfigShowReplSubCommand extends BaseCommand {
+public class ClusterConfigShowReplSubCommand extends BaseCommand implements Runnable {
/**
* Configuration selector option.
@@ -57,7 +58,6 @@ public class ClusterConfigShowReplSubCommand extends BaseCommand {
@Inject
private Session session;
- /** {@inheritDoc} */
@Override
public void run() {
var input = ClusterConfigShowCallInput.builder().selector(selector);
@@ -80,21 +80,18 @@ public class ClusterConfigShowReplSubCommand extends BaseCommand {
.runPipeline();
}
- private static class ShowConfigReplExceptionHandler implements ExceptionHandler<ApiException> {
+ private static class ShowConfigReplExceptionHandler extends IgniteCliApiExceptionHandler {
@Override
- public void handle(ExceptionWriter err, ApiException e) {
- if (e.getCode() == 500) { //TODO: https://issues.apache.org/jira/browse/IGNITE-17091
- err.write("Cannot show cluster config, probably you have not initialized the cluster. "
- + "Try to run 'cluster init' command.");
- return;
+ public int handle(ExceptionWriter err, IgniteCliApiException e) {
+ if (e.getCause() instanceof ApiException) {
+ ApiException apiException = (ApiException) e.getCause();
+ if (apiException.getCode() == 500) { //TODO: https://issues.apache.org/jira/browse/IGNITE-17091
+ err.write("Cannot show cluster config, probably you have not initialized the cluster. "
+ + "Try to run 'cluster init' command.");
+ return 1;
+ }
}
-
- err.write(e.getResponseBody());
- }
-
- @Override
- public Class<ApiException> applicableException() {
- return ApiException.class;
+ return super.handle(err, e);
}
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowSubCommand.java
index 29548c47f..0a586682f 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigShowSubCommand.java
@@ -18,6 +18,7 @@
package org.apache.ignite.cli.commands.configuration.cluster;
import jakarta.inject.Inject;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.configuration.ClusterConfigShowCall;
import org.apache.ignite.cli.call.configuration.ClusterConfigShowCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
@@ -31,7 +32,7 @@ import picocli.CommandLine.Option;
*/
@Command(name = "show",
description = "Shows cluster configuration.")
-public class ClusterConfigShowSubCommand extends BaseCommand {
+public class ClusterConfigShowSubCommand extends BaseCommand implements Callable<Integer> {
/**
* Configuration selector option.
@@ -53,8 +54,8 @@ public class ClusterConfigShowSubCommand extends BaseCommand {
/** {@inheritDoc} */
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(this::buildCallInput)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateReplSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateReplSubCommand.java
index 91ada9d0e..d3f28c9ea 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateReplSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateReplSubCommand.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Parameters;
@Command(name = "update",
description = "Updates cluster configuration.")
@Singleton
-public class ClusterConfigUpdateReplSubCommand extends BaseCommand {
+public class ClusterConfigUpdateReplSubCommand extends BaseCommand implements Runnable {
/**
* Cluster url option.
*/
@@ -69,7 +69,7 @@ public class ClusterConfigUpdateReplSubCommand extends BaseCommand {
return;
}
- CallExecutionPipeline.builder(this.call)
+ CallExecutionPipeline.builder(call)
.inputProvider(input::build)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateSubCommand.java
index 12aafaf0e..9504f78e0 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterConfigUpdateSubCommand.java
@@ -19,6 +19,7 @@ package org.apache.ignite.cli.commands.configuration.cluster;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.configuration.ClusterConfigUpdateCall;
import org.apache.ignite.cli.call.configuration.ClusterConfigUpdateCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
@@ -33,7 +34,7 @@ import picocli.CommandLine.Parameters;
@Command(name = "update",
description = "Updates cluster configuration.")
@Singleton
-public class ClusterConfigUpdateSubCommand extends BaseCommand {
+public class ClusterConfigUpdateSubCommand extends BaseCommand implements Callable<Integer> {
@Inject
ClusterConfigUpdateCall call;
@@ -54,8 +55,8 @@ public class ClusterConfigUpdateSubCommand extends BaseCommand {
/** {@inheritDoc} */
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(this::buildCallInput)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowReplSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowReplSubCommand.java
index 8cb43510f..a6894c876 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowReplSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowReplSubCommand.java
@@ -23,10 +23,7 @@ import org.apache.ignite.cli.call.configuration.NodeConfigShowCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.commands.decorators.JsonDecorator;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
-import org.apache.ignite.cli.core.exception.ExceptionHandler;
-import org.apache.ignite.cli.core.exception.ExceptionWriter;
import org.apache.ignite.cli.core.repl.Session;
-import org.apache.ignite.rest.client.invoker.ApiException;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@@ -35,7 +32,7 @@ import picocli.CommandLine.Option;
*/
@Command(name = "show",
description = "Shows node configuration.")
-public class NodeConfigShowReplSubCommand extends BaseCommand {
+public class NodeConfigShowReplSubCommand extends BaseCommand implements Runnable {
/**
* Configuration selector option.
@@ -75,26 +72,7 @@ public class NodeConfigShowReplSubCommand extends BaseCommand {
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
.decorator(new JsonDecorator())
- .exceptionHandler(new ShowConfigReplExceptionHandler())
.build()
.runPipeline();
}
-
- private static class ShowConfigReplExceptionHandler implements ExceptionHandler<ApiException> {
- @Override
- public void handle(ExceptionWriter err, ApiException e) {
- if (e.getCode() == 500) { //TODO: https://issues.apache.org/jira/browse/IGNITE-17091
- err.write("Cannot show node config, probably you have not initialized the cluster. "
- + "Try to run 'cluster init' command.");
- return;
- }
-
- err.write(e.getResponseBody());
- }
-
- @Override
- public Class<ApiException> applicableException() {
- return ApiException.class;
- }
- }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowSubCommand.java
index 56a8de470..a1a89135c 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigShowSubCommand.java
@@ -18,6 +18,7 @@
package org.apache.ignite.cli.commands.configuration.node;
import jakarta.inject.Inject;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.configuration.NodeConfigShowCall;
import org.apache.ignite.cli.call.configuration.NodeConfigShowCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
@@ -31,7 +32,7 @@ import picocli.CommandLine.Option;
*/
@Command(name = "show",
description = "Shows node configuration.")
-public class NodeConfigShowSubCommand extends BaseCommand {
+public class NodeConfigShowSubCommand extends BaseCommand implements Callable<Integer> {
/**
* Configuration selector option.
@@ -53,8 +54,8 @@ public class NodeConfigShowSubCommand extends BaseCommand {
/** {@inheritDoc} */
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(this::buildCallInput)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateReplSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateReplSubCommand.java
index 6d3116084..0a8e74671 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateReplSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateReplSubCommand.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Parameters;
@Command(name = "update",
description = "Updates node configuration.")
@Singleton
-public class NodeConfigUpdateReplSubCommand extends BaseCommand {
+public class NodeConfigUpdateReplSubCommand extends BaseCommand implements Runnable {
/**
* Node url option.
*/
@@ -69,7 +69,7 @@ public class NodeConfigUpdateReplSubCommand extends BaseCommand {
return;
}
- CallExecutionPipeline.builder(this.call)
+ CallExecutionPipeline.builder(call)
.inputProvider(input::build)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateSubCommand.java
index 08a3125e5..30896902e 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateSubCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/node/NodeConfigUpdateSubCommand.java
@@ -19,6 +19,7 @@ package org.apache.ignite.cli.commands.configuration.node;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.configuration.NodeConfigUpdateCall;
import org.apache.ignite.cli.call.configuration.NodeConfigUpdateCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
@@ -33,9 +34,7 @@ import picocli.CommandLine.Parameters;
@Command(name = "update",
description = "Updates node configuration.")
@Singleton
-public class NodeConfigUpdateSubCommand extends BaseCommand {
- @Inject
- NodeConfigUpdateCall call;
+public class NodeConfigUpdateSubCommand extends BaseCommand implements Callable<Integer> {
/**
* Node url option.
*/
@@ -44,16 +43,20 @@ public class NodeConfigUpdateSubCommand extends BaseCommand {
descriptionKey = "ignite.cluster-url", defaultValue = "http://localhost:10300"
)
private String nodeUrl;
+
/**
* Configuration that will be updated.
*/
@Parameters(index = "0")
private String config;
+ @Inject
+ private NodeConfigUpdateCall call;
+
/** {@inheritDoc} */
@Override
- public void run() {
- CallExecutionPipeline.builder(call)
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
.inputProvider(this::buildCallInput)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/ConnectCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/ConnectCommand.java
index 32a6e534a..d73a19a49 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/ConnectCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/ConnectCommand.java
@@ -24,16 +24,14 @@ import org.apache.ignite.cli.call.connect.ConnectCallInput;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Parameters;
-import picocli.CommandLine.Spec;
/**
* Connects to the Ignite 3 node.
*/
@Command(name = "connect", description = "Connect to Ignite 3 node.")
@Singleton
-public class ConnectCommand extends BaseCommand {
+public class ConnectCommand extends BaseCommand implements Runnable {
/**
* Cluster url option.
@@ -44,9 +42,6 @@ public class ConnectCommand extends BaseCommand {
)
private String nodeUrl;
- @Spec
- private CommandSpec spec;
-
@Inject
private ConnectCall connectCall;
@@ -54,10 +49,16 @@ public class ConnectCommand extends BaseCommand {
@Override
public void run() {
CallExecutionPipeline.builder(connectCall)
- .inputProvider(() -> ConnectCallInput.builder().nodeUrl(nodeUrl).build())
+ .inputProvider(this::buildCallInput)
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
.build()
.runPipeline();
}
+
+ private ConnectCallInput buildCallInput() {
+ return ConnectCallInput.builder()
+ .nodeUrl(nodeUrl)
+ .build();
+ }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/DisconnectCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/DisconnectCommand.java
index 588989507..a6da5d1a4 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/DisconnectCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/connect/DisconnectCommand.java
@@ -24,18 +24,13 @@ import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.EmptyCallInput;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
/**
* Connects to the Ignite 3 node.
*/
@Command(name = "disconnect", description = "Disconnect from Ignite 3 node.")
@Singleton
-public class DisconnectCommand extends BaseCommand {
- @Spec
- private CommandSpec spec;
-
+public class DisconnectCommand extends BaseCommand implements Runnable {
@Inject
private DisconnectCall disconnectCall;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java
index 986f4e2a8..8b68f8323 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java
@@ -17,29 +17,22 @@
package org.apache.ignite.cli.commands.sql;
-import jakarta.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.sql.SQLException;
+import java.util.concurrent.Callable;
+import org.apache.ignite.cli.call.sql.SqlQueryCall;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.commands.decorators.SqlQueryResultDecorator;
-import org.apache.ignite.cli.core.CallExecutionPipelineProvider;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.StringCallInput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
-import org.apache.ignite.cli.core.exception.ExceptionHandlers;
import org.apache.ignite.cli.core.exception.ExceptionWriter;
-import org.apache.ignite.cli.core.exception.handler.DefaultExceptionHandlers;
import org.apache.ignite.cli.core.exception.handler.SqlExceptionHandler;
-import org.apache.ignite.cli.core.repl.Repl;
-import org.apache.ignite.cli.core.repl.executor.RegistryCommandExecutor;
-import org.apache.ignite.cli.core.repl.executor.ReplExecutorProvider;
-import org.apache.ignite.cli.core.repl.executor.SqlQueryCall;
+import org.apache.ignite.cli.deprecated.IgniteCliException;
import org.apache.ignite.cli.sql.SqlManager;
-import org.apache.ignite.cli.sql.SqlSchemaProvider;
-import org.jetbrains.annotations.NotNull;
+import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@@ -47,27 +40,28 @@ import picocli.CommandLine.Option;
* Command for sql execution.
*/
@Command(name = "sql", description = "Executes SQL query.")
-public class SqlCommand extends BaseCommand {
- private static final String INTERNAL_COMMAND_PREFIX = "!";
+public class SqlCommand extends BaseCommand implements Callable<Integer> {
@Option(names = {"-u", "--jdbc-url"}, required = true,
descriptionKey = "ignite.jdbc-url", description = "JDBC url to ignite cluster")
private String jdbc;
- @Option(names = {"-e", "--execute", "--exec"}) //todo: can be passed as parameter, not option (see IEP-88)
- private String command;
+ @ArgGroup(multiplicity = "1")
+ private ExecOptions execOptions;
- @Option(names = {"-f", "--script-file"})
- private File file;
+ private static class ExecOptions {
+ @Option(names = {"-e", "--execute", "--exec"}) //todo: can be passed as parameter, not option (see IGNITE-17209)
+ private String command;
- @Inject
- private ReplExecutorProvider replExecutorProvider;
+ @Option(names = {"-f", "--script-file"})
+ private File file;
+ }
private static String extract(File file) {
try {
return String.join("\n", Files.readAllLines(file.toPath(), StandardCharsets.UTF_8));
} catch (IOException e) {
- throw new CommandExecutionException("sql", "File with command not found.");
+ throw new IgniteCliException("File with command not found.");
}
}
@@ -75,51 +69,18 @@ public class SqlCommand extends BaseCommand {
* {@inheritDoc}
*/
@Override
- public void run() {
+ public Integer call() {
try (SqlManager sqlManager = new SqlManager(jdbc)) {
- if (command == null && file == null) {
- replExecutorProvider.get().execute(Repl.builder()
- .withPromptProvider(() -> "sql-cli> ")
- .withCompleter(new SqlCompleter(new SqlSchemaProvider(sqlManager::getMetadata)))
- .withCommandClass(SqlReplTopLevelCliCommand.class)
- .withCallExecutionPipelineProvider(provider(sqlManager))
- .withHistoryFileName("sqlhistory")
- .build());
- } else {
- String executeCommand = file != null ? extract(file) : command;
- createSqlExecPipeline(sqlManager, executeCommand).runPipeline();
- }
+ String executeCommand = execOptions.file != null ? extract(execOptions.file) : execOptions.command;
+ return CallExecutionPipeline.builder(new SqlQueryCall(sqlManager))
+ .inputProvider(() -> new StringCallInput(executeCommand))
+ .output(spec.commandLine().getOut())
+ .errOutput(spec.commandLine().getErr())
+ .decorator(new SqlQueryResultDecorator())
+ .build().runPipeline();
} catch (SQLException e) {
- new SqlExceptionHandler().handle(ExceptionWriter.fromPrintWriter(spec.commandLine().getErr()), e);
+ return new SqlExceptionHandler().handle(ExceptionWriter.fromPrintWriter(spec.commandLine().getErr()), e);
}
}
- @NotNull
- private CallExecutionPipelineProvider provider(SqlManager sqlManager) {
- return (call, exceptionHandlers, line) -> line.startsWith(INTERNAL_COMMAND_PREFIX)
- ? createInternalCommandPipeline(call, exceptionHandlers, line)
- : createSqlExecPipeline(sqlManager, line);
- }
-
- private CallExecutionPipeline<?, ?> createSqlExecPipeline(SqlManager sqlManager, String line) {
- return CallExecutionPipeline.builder(new SqlQueryCall(sqlManager))
- .inputProvider(() -> new StringCallInput(line))
- .output(spec.commandLine().getOut())
- .errOutput(spec.commandLine().getErr())
- .exceptionHandlers(new DefaultExceptionHandlers())
- .decorator(new SqlQueryResultDecorator())
- .build();
- }
-
- private CallExecutionPipeline<?, ?> createInternalCommandPipeline(RegistryCommandExecutor call,
- ExceptionHandlers exceptionHandlers,
- String line) {
- return CallExecutionPipeline.builder(call)
- .inputProvider(() -> new StringCallInput(line.substring(INTERNAL_COMMAND_PREFIX.length())))
- .output(spec.commandLine().getOut())
- .errOutput(spec.commandLine().getErr())
- .exceptionHandlers(new DefaultExceptionHandlers())
- .exceptionHandlers(exceptionHandlers)
- .build();
- }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlReplCommand.java
similarity index 83%
copy from modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java
copy to modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlReplCommand.java
index 986f4e2a8..14bd83dba 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/sql/SqlReplCommand.java
@@ -23,42 +23,46 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.sql.SQLException;
+import org.apache.ignite.cli.call.sql.SqlQueryCall;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.commands.decorators.SqlQueryResultDecorator;
import org.apache.ignite.cli.core.CallExecutionPipelineProvider;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.StringCallInput;
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
import org.apache.ignite.cli.core.exception.ExceptionHandlers;
import org.apache.ignite.cli.core.exception.ExceptionWriter;
-import org.apache.ignite.cli.core.exception.handler.DefaultExceptionHandlers;
import org.apache.ignite.cli.core.exception.handler.SqlExceptionHandler;
import org.apache.ignite.cli.core.repl.Repl;
import org.apache.ignite.cli.core.repl.executor.RegistryCommandExecutor;
import org.apache.ignite.cli.core.repl.executor.ReplExecutorProvider;
-import org.apache.ignite.cli.core.repl.executor.SqlQueryCall;
+import org.apache.ignite.cli.deprecated.IgniteCliException;
import org.apache.ignite.cli.sql.SqlManager;
import org.apache.ignite.cli.sql.SqlSchemaProvider;
-import org.jetbrains.annotations.NotNull;
+import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
/**
- * Command for sql execution.
+ * Command for sql execution in REPL mode.
*/
@Command(name = "sql", description = "Executes SQL query.")
-public class SqlCommand extends BaseCommand {
+public class SqlReplCommand extends BaseCommand implements Runnable {
private static final String INTERNAL_COMMAND_PREFIX = "!";
@Option(names = {"-u", "--jdbc-url"}, required = true,
descriptionKey = "ignite.jdbc-url", description = "JDBC url to ignite cluster")
private String jdbc;
- @Option(names = {"-e", "--execute", "--exec"}) //todo: can be passed as parameter, not option (see IEP-88)
- private String command;
+ @ArgGroup
+ private ExecOptions execOptions;
- @Option(names = {"-f", "--script-file"})
- private File file;
+ private static class ExecOptions {
+ @Option(names = {"-e", "--execute", "--exec"}) //todo: can be passed as parameter, not option (see IEP-88)
+ private String command;
+
+ @Option(names = {"-f", "--script-file"})
+ private File file;
+ }
@Inject
private ReplExecutorProvider replExecutorProvider;
@@ -67,7 +71,7 @@ public class SqlCommand extends BaseCommand {
try {
return String.join("\n", Files.readAllLines(file.toPath(), StandardCharsets.UTF_8));
} catch (IOException e) {
- throw new CommandExecutionException("sql", "File with command not found.");
+ throw new IgniteCliException("File with command not found.");
}
}
@@ -77,7 +81,7 @@ public class SqlCommand extends BaseCommand {
@Override
public void run() {
try (SqlManager sqlManager = new SqlManager(jdbc)) {
- if (command == null && file == null) {
+ if (execOptions == null) {
replExecutorProvider.get().execute(Repl.builder()
.withPromptProvider(() -> "sql-cli> ")
.withCompleter(new SqlCompleter(new SqlSchemaProvider(sqlManager::getMetadata)))
@@ -86,7 +90,7 @@ public class SqlCommand extends BaseCommand {
.withHistoryFileName("sqlhistory")
.build());
} else {
- String executeCommand = file != null ? extract(file) : command;
+ String executeCommand = execOptions.file != null ? extract(execOptions.file) : execOptions.command;
createSqlExecPipeline(sqlManager, executeCommand).runPipeline();
}
} catch (SQLException e) {
@@ -94,7 +98,6 @@ public class SqlCommand extends BaseCommand {
}
}
- @NotNull
private CallExecutionPipelineProvider provider(SqlManager sqlManager) {
return (call, exceptionHandlers, line) -> line.startsWith(INTERNAL_COMMAND_PREFIX)
? createInternalCommandPipeline(call, exceptionHandlers, line)
@@ -106,7 +109,6 @@ public class SqlCommand extends BaseCommand {
.inputProvider(() -> new StringCallInput(line))
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
- .exceptionHandlers(new DefaultExceptionHandlers())
.decorator(new SqlQueryResultDecorator())
.build();
}
@@ -118,7 +120,6 @@ public class SqlCommand extends BaseCommand {
.inputProvider(() -> new StringCallInput(line.substring(INTERNAL_COMMAND_PREFIX.length())))
.output(spec.commandLine().getOut())
.errOutput(spec.commandLine().getErr())
- .exceptionHandlers(new DefaultExceptionHandlers())
.exceptionHandlers(exceptionHandlers)
.build();
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusCommand.java
index c2be4f3aa..f380046b7 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusCommand.java
@@ -19,15 +19,14 @@ package org.apache.ignite.cli.commands.status;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.call.status.StatusCall;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.commands.decorators.StatusDecorator;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.StatusCallInput;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
-import picocli.CommandLine.Spec;
/**
* Command that prints status of ignite cluster.
@@ -36,7 +35,7 @@ import picocli.CommandLine.Spec;
aliases = "cluster show", //TODO: https://issues.apache.org/jira/browse/IGNITE-17102
description = "Prints status of the cluster.")
@Singleton
-public class StatusCommand extends BaseCommand {
+public class StatusCommand extends BaseCommand implements Callable<Integer> {
/**
* Cluster url option.
@@ -48,19 +47,16 @@ public class StatusCommand extends BaseCommand {
)
private String clusterUrl;
- @Spec
- private CommandSpec commandSpec;
-
@Inject
private StatusCall statusCall;
/** {@inheritDoc} */
@Override
- public void run() {
- CallExecutionPipeline.builder(statusCall)
+ public Integer call() {
+ return CallExecutionPipeline.builder(statusCall)
.inputProvider(() -> new StatusCallInput(clusterUrl))
- .output(commandSpec.commandLine().getOut())
- .errOutput(commandSpec.commandLine().getErr())
+ .output(spec.commandLine().getOut())
+ .errOutput(spec.commandLine().getErr())
.decorator(new StatusDecorator())
.build()
.runPipeline();
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusReplCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusReplCommand.java
index 4ebb924ca..a4847df7a 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusReplCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/status/StatusReplCommand.java
@@ -25,16 +25,14 @@ import org.apache.ignite.cli.commands.decorators.StatusReplDecorator;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.EmptyCallInput;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
-import picocli.CommandLine.Spec;
/**
* Command that prints status of ignite cluster.
*/
@Command(name = "status", description = "Prints status of the cluster.")
@Singleton
-public class StatusReplCommand extends BaseCommand {
+public class StatusReplCommand extends BaseCommand implements Runnable {
/**
* Cluster url option.
@@ -45,9 +43,6 @@ public class StatusReplCommand extends BaseCommand {
)
private String clusterUrl;
- @Spec
- private CommandSpec commandSpec;
-
@Inject
private StatusReplCall statusReplCall;
@@ -56,8 +51,8 @@ public class StatusReplCommand extends BaseCommand {
public void run() {
CallExecutionPipeline.builder(statusReplCall)
.inputProvider(EmptyCallInput::new)
- .output(commandSpec.commandLine().getOut())
- .errOutput(commandSpec.commandLine().getErr())
+ .output(spec.commandLine().getOut())
+ .errOutput(spec.commandLine().getErr())
.decorator(new StatusReplDecorator())
.build()
.runPipeline();
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/topology/TopologyCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/topology/TopologyCommand.java
index 872238fb6..e01a888a4 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/topology/TopologyCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/topology/TopologyCommand.java
@@ -18,18 +18,17 @@
package org.apache.ignite.cli.commands.topology;
import jakarta.inject.Singleton;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.commands.BaseCommand;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
-import picocli.CommandLine.Spec;
/**
* Command that prints ignite cluster topology.
*/
@Command(name = "topology", description = "Prints topology information.")
@Singleton
-public class TopologyCommand extends BaseCommand {
+public class TopologyCommand extends BaseCommand implements Callable<Integer> {
/**
* Cluster url option.
@@ -41,13 +40,11 @@ public class TopologyCommand extends BaseCommand {
)
private String clusterUrl;
- @Spec
- private CommandSpec commandSpec;
-
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
//TODO: https://issues.apache.org/jira/browse/IGNITE-17092
- commandSpec.commandLine().getOut().println("Topology command is not implemented yet.");
+ spec.commandLine().getOut().println("Topology command is not implemented yet.");
+ return 0;
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/version/VersionCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/version/VersionCommand.java
index 18f5946e5..046d319e8 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/version/VersionCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/version/VersionCommand.java
@@ -20,26 +20,21 @@ package org.apache.ignite.cli.commands.version;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.VersionProvider;
+import org.apache.ignite.cli.commands.BaseCommand;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Model.CommandSpec;
-import picocli.CommandLine.Spec;
/**
* Command that prints CLI version.
*/
@Command(name = "version", description = "Prints CLI version.")
@Singleton
-public class VersionCommand implements Runnable {
-
- @Spec
- private CommandSpec commandSpec;
+public class VersionCommand extends BaseCommand implements Runnable {
@Inject
private VersionProvider versionProvider;
- /** {@inheritDoc} */
@Override
public void run() {
- commandSpec.commandLine().getOut().println(versionProvider.getVersion()[0]);
+ spec.commandLine().getOut().println(versionProvider.getVersion()[0]);
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/call/CallExecutionPipeline.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/call/CallExecutionPipeline.java
index 578ea02ae..0b75a2de8 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/call/CallExecutionPipeline.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/call/CallExecutionPipeline.java
@@ -90,24 +90,25 @@ public class CallExecutionPipeline<I extends CallInput, T> {
return new CallExecutionPipelineBuilder<>(call);
}
- /** {@inheritDoc} */
- public void runPipeline() {
+ /**
+ * Runs the pipeline.
+ *
+ * @return exit code.
+ */
+ public int runPipeline() {
I callInput = inputProvider.get();
CallOutput<T> callOutput = call.execute(callInput);
if (callOutput.hasError()) {
- exceptionHandlers.handleException(ExceptionWriter.fromPrintWriter(errOutput), callOutput.errorCause());
- return;
+ return exceptionHandlers.handleException(ExceptionWriter.fromPrintWriter(errOutput), callOutput.errorCause());
}
- if (callOutput.isEmpty()) {
- return;
+ if (!callOutput.isEmpty()) {
+ TerminalOutput decoratedOutput = decorator.decorate(callOutput.body());
+ output.println(decoratedOutput.toTerminalString());
}
-
- TerminalOutput decoratedOutput = decorator.decorate(callOutput.body());
-
- output.println(decoratedOutput.toTerminalString());
+ return 0;
}
/** Builder for {@link CallExecutionPipeline}. */
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/call/StatusCallInput.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/call/StatusCallInput.java
index 74aab7f89..8d2dad95e 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/call/StatusCallInput.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/call/StatusCallInput.java
@@ -30,4 +30,5 @@ public class StatusCallInput implements CallInput {
public String getClusterUrl() {
return clusterUrl;
}
+
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandler.java
index e16798b69..99ea03858 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandler.java
@@ -30,9 +30,10 @@ public interface ExceptionHandler<T extends Throwable> {
ExceptionHandler<Throwable> DEFAULT = new ExceptionHandler<>() {
@Override
- public void handle(ExceptionWriter err, Throwable e) {
+ public int handle(ExceptionWriter err, Throwable e) {
logger.error("Unhandled exception ", e);
err.write("Internal error!");
+ return 1;
}
@Override
@@ -42,12 +43,13 @@ public interface ExceptionHandler<T extends Throwable> {
};
/**
- * Handler method.
+ * Handles an exception.
*
* @param err writer instance for any error messages.
* @param e exception instance.
+ * @return exit code.
*/
- void handle(ExceptionWriter err, T e);
+ int handle(ExceptionWriter err, T e);
/**
* Exception class getter.
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandlers.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandlers.java
index 09437e679..d2a6c69c5 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandlers.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/ExceptionHandlers.java
@@ -56,23 +56,24 @@ public class ExceptionHandlers {
}
/**
- * Handle method.
+ * Handles an exception.
*
* @param errOutput error output.
* @param e exception instance.
* @param <T> exception type.
+ * @return exit code.
*/
- public <T extends Throwable> void handleException(ExceptionWriter errOutput, T e) {
- processException(errOutput, e instanceof WrappedException ? e.getCause() : e);
+ public <T extends Throwable> int handleException(ExceptionWriter errOutput, T e) {
+ return processException(errOutput, e instanceof WrappedException ? e.getCause() : e);
}
@SuppressWarnings("unchecked")
- private <T extends Throwable> void processException(ExceptionWriter errOutput, T e) {
+ private <T extends Throwable> int processException(ExceptionWriter errOutput, T e) {
ExceptionHandler<T> exceptionHandler = (ExceptionHandler<T>) map.get(e.getClass());
if (exceptionHandler != null) {
- exceptionHandler.handle(errOutput, e);
+ return exceptionHandler.handle(errOutput, e);
} else {
- defaultHandler.handle(errOutput, e);
+ return defaultHandler.handle(errOutput, e);
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ApiExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/IgniteCliApiException.java
similarity index 57%
rename from modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ApiExceptionHandler.java
rename to modules/cli/src/main/java/org/apache/ignite/cli/core/exception/IgniteCliApiException.java
index f581f579a..e247be9d6 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ApiExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/IgniteCliApiException.java
@@ -15,23 +15,32 @@
* limitations under the License.
*/
-package org.apache.ignite.cli.core.exception.handler;
-
-import org.apache.ignite.cli.core.exception.ExceptionHandler;
-import org.apache.ignite.cli.core.exception.ExceptionWriter;
-import org.apache.ignite.rest.client.invoker.ApiException;
+package org.apache.ignite.cli.core.exception;
/**
- * Exception handler for {@link ApiException}.
+ * Top level runtime exception for throwing the error message from REST API to user.
*/
-public class ApiExceptionHandler implements ExceptionHandler<ApiException> {
- @Override
- public void handle(ExceptionWriter err, ApiException e) {
- err.write("Api error: " + e.getCause());
+public class IgniteCliApiException extends RuntimeException {
+
+ private final String url;
+
+ /**
+ * Creates a new instance of {@code IgniteCliApiException}.
+ *
+ * @param cause the cause.
+ * @param url endpoint URL.
+ */
+ public IgniteCliApiException(Throwable cause, String url) {
+ super(cause);
+ this.url = url;
}
- @Override
- public Class<ApiException> applicableException() {
- return ApiException.class;
+ /**
+ * Gets the endpoint URL.
+ *
+ * @return endpoint URL.
+ */
+ public String getUrl() {
+ return url;
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/CommandExecutionExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/CommandExecutionExceptionHandler.java
deleted file mode 100644
index 36240644f..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/CommandExecutionExceptionHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cli.core.exception.handler;
-
-import org.apache.ignite.cli.core.exception.CommandExecutionException;
-import org.apache.ignite.cli.core.exception.ExceptionHandler;
-import org.apache.ignite.cli.core.exception.ExceptionWriter;
-import org.apache.ignite.lang.IgniteLogger;
-
-/**
- * Exception handler for {@link CommandExecutionException}.
- */
-public class CommandExecutionExceptionHandler implements ExceptionHandler<CommandExecutionException> {
- private static final IgniteLogger log = IgniteLogger.forClass(CommandExecutionExceptionHandler.class);
-
- @Override
- public void handle(ExceptionWriter err, CommandExecutionException e) {
- log.error("Command {} failed with reason {}", e.getCommandId(), e.getReason(), e);
- err.write(String.format("Command %s failed with reason: %s", e.getCommandId(), e.getReason()));
- }
-
- @Override
- public Class<CommandExecutionException> applicableException() {
- return CommandExecutionException.class;
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ConnectCommandExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ConnectCommandExceptionHandler.java
deleted file mode 100644
index 2519fda17..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ConnectCommandExceptionHandler.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cli.core.exception.handler;
-
-import org.apache.ignite.cli.core.exception.ConnectCommandException;
-import org.apache.ignite.cli.core.exception.ExceptionHandler;
-import org.apache.ignite.cli.core.exception.ExceptionWriter;
-
-/**
- * Exception handler for {@link ConnectCommandException}.
- */
-public class ConnectCommandExceptionHandler implements ExceptionHandler<ConnectCommandException> {
- @Override
- public void handle(ExceptionWriter err, ConnectCommandException e) {
- err.write(e.getReason());
- }
-
- @Override
- public Class<ConnectCommandException> applicableException() {
- return ConnectCommandException.class;
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ConnectExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ConnectExceptionHandler.java
deleted file mode 100644
index 516e2e6a9..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/ConnectExceptionHandler.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cli.core.exception.handler;
-
-import java.net.ConnectException;
-import org.apache.ignite.cli.core.exception.ExceptionHandler;
-import org.apache.ignite.cli.core.exception.ExceptionWriter;
-
-/**
- * Exception handler for {@link ConnectException}.
- */
-public class ConnectExceptionHandler implements ExceptionHandler<ConnectException> {
- @Override
- public void handle(ExceptionWriter err, ConnectException e) {
- err.write("Connection failed " + e.getMessage());
- }
-
- @Override
- public Class<ConnectException> applicableException() {
- return ConnectException.class;
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/DefaultExceptionHandlers.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/DefaultExceptionHandlers.java
index 175fb7e71..ca00a9615 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/DefaultExceptionHandlers.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/DefaultExceptionHandlers.java
@@ -29,13 +29,10 @@ public class DefaultExceptionHandlers extends ExceptionHandlers {
*/
public DefaultExceptionHandlers() {
addExceptionHandler(new SqlExceptionHandler());
- addExceptionHandler(new ConnectCommandExceptionHandler());
- addExceptionHandler(new CommandExecutionExceptionHandler());
addExceptionHandler(new TimeoutExceptionHandler());
addExceptionHandler(new IgniteClientExceptionHandler());
addExceptionHandler(new IgniteCliExceptionHandler());
- addExceptionHandler(new ConnectExceptionHandler());
- addExceptionHandler(new ApiExceptionHandler());
+ addExceptionHandler(new IgniteCliApiExceptionHandler());
addExceptionHandler(new UnknownCommandExceptionHandler());
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/EndOfFileExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/EndOfFileExceptionHandler.java
index 64d1f85ff..cf0698a40 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/EndOfFileExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/EndOfFileExceptionHandler.java
@@ -44,8 +44,9 @@ public class EndOfFileExceptionHandler implements ExceptionHandler<EndOfFileExce
}
@Override
- public void handle(ExceptionWriter err, EndOfFileException e) {
+ public int handle(ExceptionWriter err, EndOfFileException e) {
endAction.accept(true);
+ return 1;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliApiExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliApiExceptionHandler.java
new file mode 100644
index 000000000..56f2b1341
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliApiExceptionHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cli.core.exception.handler;
+
+import java.net.ConnectException;
+import java.net.UnknownHostException;
+import org.apache.ignite.cli.core.exception.ExceptionHandler;
+import org.apache.ignite.cli.core.exception.ExceptionWriter;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
+import org.apache.ignite.lang.IgniteLogger;
+import org.apache.ignite.rest.client.invoker.ApiException;
+
+/**
+ * Exception handler for {@link IgniteCliApiException}.
+ */
+public class IgniteCliApiExceptionHandler implements ExceptionHandler<IgniteCliApiException> {
+ private static final IgniteLogger log = IgniteLogger.forClass(IgniteCliApiExceptionHandler.class);
+
+ @Override
+ public int handle(ExceptionWriter err, IgniteCliApiException e) {
+ String message;
+
+ if (e.getCause() instanceof ApiException) {
+ ApiException cause = (ApiException) e.getCause();
+ Throwable apiCause = cause.getCause();
+ if (apiCause instanceof UnknownHostException) {
+ message = "Could not determine IP address when connecting to URL: " + e.getUrl();
+ } else if (apiCause instanceof ConnectException) {
+ message = "Could not connect to URL: " + e.getUrl();
+ } else if (apiCause != null) {
+ message = apiCause.getMessage();
+ } else {
+ message = "An error occurred, error code: " + cause.getCode() + ", response: " + cause.getResponseBody();
+ }
+ } else {
+ message = e.getCause() != e ? e.getCause().getMessage() : e.getMessage();
+ }
+
+ log.error(message, e);
+
+ err.write(message);
+
+ return 1;
+ }
+
+ @Override
+ public Class<IgniteCliApiException> applicableException() {
+ return IgniteCliApiException.class;
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliExceptionHandler.java
index 03cf5a72b..0d9862080 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteCliExceptionHandler.java
@@ -26,8 +26,9 @@ import org.apache.ignite.cli.deprecated.IgniteCliException;
*/
public class IgniteCliExceptionHandler implements ExceptionHandler<IgniteCliException> {
@Override
- public void handle(ExceptionWriter err, IgniteCliException e) {
+ public int handle(ExceptionWriter err, IgniteCliException e) {
err.write(e.getMessage());
+ return 1;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteClientExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteClientExceptionHandler.java
index 765d3e280..b013427ab 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteClientExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/IgniteClientExceptionHandler.java
@@ -29,9 +29,10 @@ public class IgniteClientExceptionHandler implements ExceptionHandler<IgniteClie
private static final IgniteLogger log = IgniteLogger.forClass(IgniteClientExceptionHandler.class);
@Override
- public void handle(ExceptionWriter err, IgniteClientException e) {
+ public int handle(ExceptionWriter err, IgniteClientException e) {
log.error("Ignite client exception", e);
err.write("Ignite client exception with code: " + e.errorCode());
+ return 1;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/PicocliExecutionExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/PicocliExecutionExceptionHandler.java
index 939db3c14..9c96a8b0d 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/PicocliExecutionExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/PicocliExecutionExceptionHandler.java
@@ -30,7 +30,6 @@ public class PicocliExecutionExceptionHandler implements IExecutionExceptionHand
@Override
public int handleExecutionException(Exception ex, CommandLine commandLine, ParseResult parseResult) {
- exceptionHandlers.handleException(System.err::println, ex);
- return 1;
+ return exceptionHandlers.handleException(System.err::println, ex);
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
index 3f60ad941..af1f103b7 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/SqlExceptionHandler.java
@@ -38,7 +38,7 @@ public class SqlExceptionHandler implements ExceptionHandler<SQLException> {
public static final String CONNECTION_BROKE_MESSAGE = "Connection error.";
@Override
- public void handle(ExceptionWriter err, SQLException e) {
+ public int handle(ExceptionWriter err, SQLException e) {
switch (e.getSQLState()) {
case SqlStateCode.CONNECTION_FAILURE:
case SqlStateCode.CONNECTION_CLOSED:
@@ -58,6 +58,7 @@ public class SqlExceptionHandler implements ExceptionHandler<SQLException> {
log.error("Unrecognized error ", e);
err.write("Unrecognized error while process SQL query.");
}
+ return 1;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/TimeoutExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/TimeoutExceptionHandler.java
index 86a6881ba..582f10d2b 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/TimeoutExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/TimeoutExceptionHandler.java
@@ -29,9 +29,10 @@ public class TimeoutExceptionHandler implements ExceptionHandler<TimeoutExceptio
private static final IgniteLogger log = IgniteLogger.forClass(TimeoutExceptionHandler.class);
@Override
- public void handle(ExceptionWriter err, TimeoutException e) {
+ public int handle(ExceptionWriter err, TimeoutException e) {
log.error("Timeout exception ", e);
err.write("Command failed with timeout.");
+ return 1;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UnknownCommandExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UnknownCommandExceptionHandler.java
index 989d05055..5750ecdcd 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UnknownCommandExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UnknownCommandExceptionHandler.java
@@ -28,8 +28,10 @@ import org.jline.console.impl.SystemRegistryImpl.UnknownCommandException;
public class UnknownCommandExceptionHandler implements ExceptionHandler<UnknownCommandException> {
@Override
- public void handle(ExceptionWriter err, UnknownCommandException e) {
+ public int handle(ExceptionWriter err, UnknownCommandException e) {
err.write(e.getMessage());
+ // This exception is only thrown in the REPL mode so the return value is irrelevant, but we use 2 to keep it consistent
+ return 2;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UserInterruptExceptionHandler.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UserInterruptExceptionHandler.java
index 46da1ee2e..4dae0d079 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UserInterruptExceptionHandler.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/exception/handler/UserInterruptExceptionHandler.java
@@ -26,8 +26,9 @@ import org.jline.reader.UserInterruptException;
*/
public class UserInterruptExceptionHandler implements ExceptionHandler<UserInterruptException> {
@Override
- public void handle(ExceptionWriter err, UserInterruptException e) {
+ public int handle(ExceptionWriter err, UserInterruptException e) {
//NOOP
+ return 1;
}
@Override
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java
index 90b3b057d..2a89e8707 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java
@@ -32,6 +32,7 @@ import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.List;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
import org.apache.ignite.cli.deprecated.IgniteCliException;
/**
@@ -81,7 +82,7 @@ public class ClusterApiClient {
try {
httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
- throw new IgniteCliException("Connection issues while trying to send http request", e);
+ throw new IgniteCliApiException(e, nodeEndpoint);
}
if (httpResponse.statusCode() == HttpURLConnection.HTTP_OK) {
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/BootstrapIgniteCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/BootstrapIgniteCommandSpec.java
index 84ad3fbb5..af00c5a31 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/BootstrapIgniteCommandSpec.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/BootstrapIgniteCommandSpec.java
@@ -19,6 +19,7 @@ package org.apache.ignite.cli.deprecated.spec;
import jakarta.inject.Inject;
import java.net.URL;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.common.IgniteCommand;
import org.apache.ignite.cli.deprecated.builtins.init.InitIgniteCommand;
@@ -30,7 +31,7 @@ import picocli.CommandLine;
* @see IgniteCommand
*/
@CommandLine.Command(name = "bootstrap", description = "Installs Ignite core modules locally.")
-public class BootstrapIgniteCommandSpec extends BaseCommand implements IgniteCommand {
+public class BootstrapIgniteCommandSpec extends BaseCommand implements IgniteCommand, Callable<Integer> {
/** Init command implementation. */
@Inject
private InitIgniteCommand cmd;
@@ -44,7 +45,9 @@ public class BootstrapIgniteCommandSpec extends BaseCommand implements IgniteCom
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
cmd.init(urls, spec.commandLine().getOut(), spec.commandLine().getColorScheme());
+
+ return 0;
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java
index cd15643cb..b4389edca 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java
@@ -20,6 +20,7 @@ package org.apache.ignite.cli.deprecated.spec;
import jakarta.inject.Inject;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.deprecated.builtins.cluster.ClusterApiClient;
import picocli.CommandLine;
@@ -40,7 +41,7 @@ public class ClusterCommandSpec {
* Initializes an Ignite cluster.
*/
@CommandLine.Command(name = "init", description = "Initializes an Ignite cluster.")
- public static class InitClusterCommandSpec extends BaseCommand {
+ public static class InitClusterCommandSpec extends BaseCommand implements Callable<Integer> {
@Inject
private ClusterApiClient clusterApiClient;
@@ -80,7 +81,7 @@ public class ClusterCommandSpec {
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
clusterApiClient.init(
nodeEndpoint,
metaStorageNodes,
@@ -88,6 +89,7 @@ public class ClusterCommandSpec {
clusterName,
spec.commandLine().getOut()
);
+ return 0;
}
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java
index d5039f6ad..107f2d2f7 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java
@@ -41,7 +41,7 @@ public class ClusterReplCommandSpec {
* Initializes an Ignite cluster.
*/
@CommandLine.Command(name = "init", description = "Initializes an Ignite cluster.")
- public static class InitClusterCommandSpec extends BaseCommand {
+ public static class InitClusterCommandSpec extends BaseCommand implements Runnable {
@Inject
private ClusterApiClient clusterApiClient;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/NodeCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/NodeCommandSpec.java
index 0114de2eb..e4d9bcb4d 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/NodeCommandSpec.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/NodeCommandSpec.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.util.List;
+import java.util.concurrent.Callable;
import org.apache.ignite.cli.commands.BaseCommand;
import org.apache.ignite.cli.deprecated.CliPathsConfigLoader;
import org.apache.ignite.cli.deprecated.IgniteCliException;
@@ -50,7 +51,7 @@ public class NodeCommandSpec {
* Starts Ignite node command.
*/
@CommandLine.Command(name = "start", description = "Starts an Ignite node locally.")
- public static class StartNodeCommandSpec extends BaseCommand {
+ public static class StartNodeCommandSpec extends BaseCommand implements Callable<Integer> {
/** Loader for Ignite distributive paths. */
@Inject
@@ -70,7 +71,7 @@ public class NodeCommandSpec {
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
IgnitePaths ignitePaths = cliPathsCfgLdr.loadIgnitePathsOrThrowError();
PrintWriter out = spec.commandLine().getOut();
@@ -97,6 +98,7 @@ public class NodeCommandSpec {
tbl.addRow("@|bold Log File|@", node.logFile);
out.println(tbl);
+ return 0;
}
}
@@ -104,7 +106,7 @@ public class NodeCommandSpec {
* Command for stopping Ignite node on the current machine.
*/
@CommandLine.Command(name = "stop", description = "Stops a locally running Ignite node.")
- public static class StopNodeCommandSpec extends BaseCommand {
+ public static class StopNodeCommandSpec extends BaseCommand implements Callable<Integer> {
/** Node manager. */
@Inject
private NodeManager nodeMgr;
@@ -123,7 +125,7 @@ public class NodeCommandSpec {
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
IgnitePaths ignitePaths = cliPathsCfgLdr.loadIgnitePathsOrThrowError();
PrintWriter out = spec.commandLine().getOut();
@@ -138,6 +140,7 @@ public class NodeCommandSpec {
out.println(cs.text("@|bold,red Failed|@"));
}
});
+ return 0;
}
}
@@ -145,7 +148,7 @@ public class NodeCommandSpec {
* Command for listing the running nodes.
*/
@CommandLine.Command(name = "list", description = "Shows the list of currently running local Ignite nodes.")
- public static class ListNodesCommandSpec extends BaseCommand {
+ public static class ListNodesCommandSpec extends BaseCommand implements Callable<Integer> {
/** Node manager. */
@Inject
private NodeManager nodeMgr;
@@ -156,7 +159,7 @@ public class NodeCommandSpec {
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
IgnitePaths paths = cliPathsCfgLdr.loadIgnitePathsOrThrowError();
List<NodeManager.RunningNode> nodes = nodeMgr.getRunningNodes(paths.logDir, paths.cliPidsDir());
@@ -183,6 +186,7 @@ public class NodeCommandSpec {
out.println(tbl);
}
+ return 0;
}
}
@@ -190,14 +194,14 @@ public class NodeCommandSpec {
* Command for reading the current classpath of Ignite nodes.
*/
@CommandLine.Command(name = "classpath", description = "Shows the current classpath used by the Ignite nodes.")
- public static class NodesClasspathCommandSpec extends BaseCommand {
+ public static class NodesClasspathCommandSpec extends BaseCommand implements Callable<Integer> {
/** Node manager. */
@Inject
private NodeManager nodeMgr;
/** {@inheritDoc} */
@Override
- public void run() {
+ public Integer call() {
try {
List<String> items = nodeMgr.classpathItems();
@@ -211,6 +215,7 @@ public class NodeCommandSpec {
} catch (IOException e) {
throw new IgniteCliException("Can't get current classpath", e);
}
+ return 0;
}
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/sql/SqlSchemaLoader.java b/modules/cli/src/main/java/org/apache/ignite/cli/sql/SqlSchemaLoader.java
index 2b03119bf..7a155e7c7 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/sql/SqlSchemaLoader.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/sql/SqlSchemaLoader.java
@@ -50,7 +50,7 @@ public class SqlSchemaLoader {
tables.put(tableName, loadColumns(tableSchema, tableName));
}
} catch (SQLException e) {
- //TODO: https://issues.apache.org/jira/browse/IGNITE-17093
+ //TODO: https://issues.apache.org/jira/browse/IGNITE-17090
}
return new SqlSchema(schema);
}
@@ -64,7 +64,7 @@ public class SqlSchemaLoader {
columns.add(rs.getString("COLUMN_NAME"));
}
} catch (SQLException e) {
- //TODO: https://issues.apache.org/jira/browse/IGNITE-17093
+ //TODO: https://issues.apache.org/jira/browse/IGNITE-17090
}
return columns;
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/CliCommandTestBase.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/CliCommandTestBase.java
index 4e5209c84..dfe2106a3 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/commands/CliCommandTestBase.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/CliCommandTestBase.java
@@ -17,39 +17,103 @@
package org.apache.ignite.cli.commands;
+import static org.assertj.core.api.Assertions.assertThat;
+
import io.micronaut.configuration.picocli.MicronautFactory;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import java.io.PrintWriter;
import java.io.StringWriter;
+import org.junit.jupiter.api.BeforeEach;
import picocli.CommandLine;
/**
* Base class for testing CLI commands.
*/
@MicronautTest
-public class CliCommandTestBase {
+public abstract class CliCommandTestBase {
@Inject
private ApplicationContext context;
- private CommandLine commandLine;
+ private CommandLine cmd;
- protected StringWriter err;
+ private StringWriter sout;
- protected StringWriter out;
+ private StringWriter serr;
private int exitCode = Integer.MIN_VALUE;
- protected void setUp(Class<?> commandClass) {
- err = new StringWriter();
- out = new StringWriter();
- commandLine = new CommandLine(commandClass, new MicronautFactory(context));
- commandLine.setErr(new PrintWriter(err));
- commandLine.setOut(new PrintWriter(out));
+ @BeforeEach
+ public void setUp() {
+ cmd = new CommandLine(getCommandClass(), new MicronautFactory(context));
+ sout = new StringWriter();
+ serr = new StringWriter();
+ cmd.setOut(new PrintWriter(sout));
+ cmd.setErr(new PrintWriter(serr));
}
+ protected abstract Class<?> getCommandClass();
+
protected void execute(String... args) {
- exitCode = commandLine.execute(args);
+ exitCode = cmd.execute(args);
+ }
+
+ protected void assertExitCodeIs(int expectedExitCode) {
+ assertThat(exitCode)
+ .as("Expected exit code to be: " + expectedExitCode + " but was " + exitCode)
+ .isEqualTo(expectedExitCode);
+ }
+
+ protected void assertExitCodeIsZero() {
+ assertExitCodeIs(0);
+ }
+
+ protected void assertOutputIsNotEmpty() {
+ assertThat(sout.toString())
+ .as("Expected command output not to be empty")
+ .isNotEmpty();
+ }
+
+ protected void assertOutputIs(String expectedOutput) {
+ assertThat(sout.toString())
+ .as("Expected command output to be: " + expectedOutput + " but was " + sout.toString())
+ .isEqualTo(expectedOutput);
+ }
+
+ protected void assertOutputContains(String expectedOutput) {
+ assertThat(sout.toString())
+ .as("Expected command output to contain: " + expectedOutput + " but was " + sout.toString())
+ .contains(expectedOutput);
+ }
+
+ protected void assertOutputIsEmpty() {
+ assertThat(sout.toString())
+ .as("Expected command output to be empty")
+ .isEmpty();
+ }
+
+ protected void assertErrOutputIsNotEmpty() {
+ assertThat(serr.toString())
+ .as("Expected command error output not to be empty")
+ .isNotEmpty();
+ }
+
+ protected void assertErrOutputIsEmpty() {
+ assertThat(serr.toString())
+ .as("Expected command error output to be empty")
+ .isEmpty();
+ }
+
+ protected void assertErrOutputIs(String expectedErrOutput) {
+ assertThat(serr.toString())
+ .as("Expected command error output to be equal to: " + expectedErrOutput)
+ .isEqualTo(expectedErrOutput);
+ }
+
+ protected void assertErrOutputContains(String expectedErrOutput) {
+ assertThat(serr.toString())
+ .as("Expected command error output to contain: " + expectedErrOutput + " but was " + serr.toString())
+ .contains(expectedErrOutput);
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/UrlOptionsNegativeTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/UrlOptionsNegativeTest.java
new file mode 100644
index 000000000..aa9098b24
--- /dev/null
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/UrlOptionsNegativeTest.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cli.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+import io.micronaut.configuration.picocli.MicronautFactory;
+import io.micronaut.context.ApplicationContext;
+import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
+import jakarta.inject.Inject;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.cli.commands.configuration.cluster.ClusterConfigShowReplSubCommand;
+import org.apache.ignite.cli.commands.configuration.cluster.ClusterConfigShowSubCommand;
+import org.apache.ignite.cli.commands.configuration.cluster.ClusterConfigUpdateReplSubCommand;
+import org.apache.ignite.cli.commands.configuration.cluster.ClusterConfigUpdateSubCommand;
+import org.apache.ignite.cli.commands.configuration.node.NodeConfigShowReplSubCommand;
+import org.apache.ignite.cli.commands.configuration.node.NodeConfigShowSubCommand;
+import org.apache.ignite.cli.commands.configuration.node.NodeConfigUpdateReplSubCommand;
+import org.apache.ignite.cli.commands.configuration.node.NodeConfigUpdateSubCommand;
+import org.apache.ignite.cli.commands.connect.ConnectCommand;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import picocli.CommandLine;
+
+/**
+ * Tests error handling with various invalid URLs in CLI commands that use REST.
+ */
+@MicronautTest
+public class UrlOptionsNegativeTest {
+ private static final String NODE_URL = "http://localhost:10300";
+
+ @Inject
+ private ApplicationContext context;
+
+ private CommandLine cmd;
+
+ private StringWriter sout;
+
+ private StringWriter serr;
+
+ private int exitCode = Integer.MIN_VALUE;
+
+ private void setUp(Class<?> cmdClass) {
+ cmd = new CommandLine(cmdClass, new MicronautFactory(context));
+ sout = new StringWriter();
+ serr = new StringWriter();
+ cmd.setOut(new PrintWriter(sout));
+ cmd.setErr(new PrintWriter(serr));
+ }
+
+ private void execute(Class<?> cmdClass, String urlOptionName, String urlOptionValue, List<String> additionalOptions) {
+ setUp(cmdClass);
+ List<String> options = new ArrayList<>();
+ options.add(urlOptionName + urlOptionValue);
+ options.addAll(additionalOptions);
+ exitCode = cmd.execute(options.toArray(new String[0]));
+ }
+
+ static List<Arguments> cmdClassAndOptionsProvider() {
+ return List.of(
+ Arguments.arguments(NodeConfigShowSubCommand.class, "--node-url=", List.of()),
+ Arguments.arguments(NodeConfigUpdateSubCommand.class, "--node-url=", List.of("{key: value}")),
+ Arguments.arguments(ClusterConfigShowSubCommand.class, "--cluster-url=", List.of()),
+ Arguments.arguments(ClusterConfigUpdateSubCommand.class, "--cluster-url=", List.of("{key: value}"))
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17091
+ // Arguments.arguments(StatusCommand.class, "--cluster-url=", List.of()),
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17102
+ // Arguments.arguments(ClusterShowCommand.class, "--cluster-url=", List.of()),
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17092
+ // Arguments.arguments(TopologyCommand.class, "--cluster-url", List.of()),
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17162
+ // Arguments.arguments(ClusterCommandSpec.InitClusterCommandSpec.class, "---cluster-url=",
+ // List.of("--cluster-name=cluster", "--meta-storage-node=test"))
+ );
+ }
+
+ static List<Arguments> cmdReplClassAndOptionsProvider() {
+ return List.of(
+ Arguments.arguments(NodeConfigShowReplSubCommand.class, "--node-url=", List.of()),
+ Arguments.arguments(NodeConfigUpdateReplSubCommand.class, "--node-url=", List.of("{key: value}")),
+ Arguments.arguments(ClusterConfigShowReplSubCommand.class, "--cluster-url=", List.of()),
+ Arguments.arguments(ClusterConfigUpdateReplSubCommand.class, "--cluster-url=", List.of("{key: value}")),
+ Arguments.arguments(ConnectCommand.class, "", List.of())
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17091
+ // Arguments.arguments(StatusReplCommand.class, "--cluster-url=", List.of()),
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17102
+ // Arguments.arguments(ClusterShowReplCommand.class, "--cluster-url=", List.of()),
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17092
+ // Arguments.arguments(TopologyReplCommand.class, "--cluster-url", List.of()),
+ // TODO https://issues.apache.org/jira/browse/IGNITE-17162
+ // Arguments.arguments(ClusterReplCommandSpec.InitClusterCommandSpec.class, "---cluster-url=",
+ // List.of("--cluster-name=cluster", "--meta-storage-node=test"))
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdClassAndOptionsProvider")
+ @DisplayName("Should display error when wrong port is given")
+ void incorrectPort(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, NODE_URL + "incorrect", additionalOptions);
+
+ assertAll(
+ this::assertExitCodeIsFailure,
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Invalid URL port: \"10300incorrect\"" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdClassAndOptionsProvider")
+ @DisplayName("Should display error when wrong url is given")
+ void invalidUrlScheme(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, "incorrect" + NODE_URL, additionalOptions);
+
+ assertAll(
+ this::assertExitCodeIsFailure,
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Expected URL scheme 'http' or 'https' but was 'incorrecthttp'" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdClassAndOptionsProvider")
+ @DisplayName("Should display error when unknown host is given")
+ void invalidUrl(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, "http://no-such-host.com", additionalOptions);
+
+ assertAll(
+ this::assertExitCodeIsFailure,
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Could not determine IP address when connecting to URL: http://no-such-host.com" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdClassAndOptionsProvider")
+ @DisplayName("Should display error when failed to connect to host")
+ void connectError(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, NODE_URL, additionalOptions);
+
+ assertAll(
+ this::assertExitCodeIsFailure,
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Could not connect to URL: " + NODE_URL + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdReplClassAndOptionsProvider")
+ @DisplayName("Should display error when wrong port is given")
+ void incorrectPortRepl(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, NODE_URL + "incorrect", additionalOptions);
+
+ assertAll(
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Invalid URL port: \"10300incorrect\"" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdReplClassAndOptionsProvider")
+ @DisplayName("Should display error when wrong url is given")
+ void invalidUrlSchemeRepl(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, "incorrect" + NODE_URL, additionalOptions);
+
+ assertAll(
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Expected URL scheme 'http' or 'https' but was 'incorrecthttp'" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdReplClassAndOptionsProvider")
+ @DisplayName("Should display error when unknown host is given")
+ void invalidUrlRepl(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, "http://no-such-host.com", additionalOptions);
+
+ assertAll(
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Could not determine IP address when connecting to URL: http://no-such-host.com" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("cmdReplClassAndOptionsProvider")
+ @DisplayName("Should display error when failed to connect to host")
+ void connectErrorRepl(Class<?> cmdClass, String urlOptionName, List<String> additionalOptions) {
+ execute(cmdClass, urlOptionName, NODE_URL, additionalOptions);
+
+ assertAll(
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputIs("Could not connect to URL: " + NODE_URL + System.lineSeparator())
+ );
+ }
+
+ private void assertExitCodeIsFailure() {
+ assertThat(exitCode)
+ .as("Check exit code")
+ .isEqualTo(1);
+ }
+
+ private void assertOutputIsEmpty() {
+ assertThat(sout.toString())
+ .as("Check command output")
+ .isEmpty();
+ }
+
+ private void assertErrOutputIs(String expectedErrOutput) {
+ assertThat(serr.toString())
+ .as("Check command error output")
+ .isEqualTo(expectedErrOutput);
+ }
+
+}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommandTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommandTest.java
index 94f7a02a7..26c4c196b 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommandTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigGetSubCommandTest.java
@@ -17,18 +17,17 @@
package org.apache.ignite.cli.commands.cliconfig;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
import org.apache.ignite.cli.commands.CliCommandTestBase;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
class CliConfigGetSubCommandTest extends CliCommandTestBase {
- @BeforeEach
- void setUp() {
- setUp(CliConfigGetSubCommand.class);
+ @Override
+ protected Class<?> getCommandClass() {
+ return CliConfigGetSubCommand.class;
}
@Test
@@ -37,10 +36,11 @@ class CliConfigGetSubCommandTest extends CliCommandTestBase {
// When executed without arguments
execute();
- // Then
- assertThat(err.toString()).contains("Missing required parameter: '<key>'");
- // And
- assertThat(out.toString()).isEmpty();
+ assertAll(
+ () -> assertExitCodeIs(2),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Missing required parameter: '<key>'")
+ );
}
@Test
@@ -49,22 +49,24 @@ class CliConfigGetSubCommandTest extends CliCommandTestBase {
// When executed with single key
execute("ignite.cluster-url");
- // Then
- assertThat(out.toString()).isEqualTo("test_cluster_url" + System.lineSeparator());
- // And
- assertThat(err.toString()).isEmpty();
+ assertAll(
+ this::assertExitCodeIsZero,
+ () -> assertOutputIs("test_cluster_url" + System.lineSeparator()),
+ this::assertErrOutputIsEmpty
+ );
}
@Test
- @DisplayName("Displays error for nonexistent key")
+ @DisplayName("Displays empty string for nonexistent key")
void nonexistentKey() {
// When executed with nonexistent key
execute("nonexistentKey");
- // Then
- assertThat(err.toString()).isEmpty();
- // And
- assertThat(out.toString().trim()).isEmpty();
+ assertAll(
+ this::assertExitCodeIsZero,
+ () -> assertOutputIs(System.lineSeparator()),
+ this::assertErrOutputIsEmpty
+ );
}
@Test
@@ -73,9 +75,10 @@ class CliConfigGetSubCommandTest extends CliCommandTestBase {
// When executed with multiple keys
execute("ignite.cluster-url", "ignite.jdbc-url");
- // Then
- assertThat(err.toString()).contains("Unmatched argument at index 1");
- // And
- assertThat(out.toString()).isEmpty();
+ assertAll(
+ () -> assertExitCodeIs(2),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Unmatched argument at index 1")
+ );
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommandTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommandTest.java
index 0ca5a1b9a..2235ffff8 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommandTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSetSubCommandTest.java
@@ -18,11 +18,11 @@
package org.apache.ignite.cli.commands.cliconfig;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
import jakarta.inject.Inject;
import org.apache.ignite.cli.commands.CliCommandTestBase;
import org.apache.ignite.cli.config.Config;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -31,9 +31,9 @@ class CliConfigSetSubCommandTest extends CliCommandTestBase {
@Inject
Config config;
- @BeforeEach
- void setUp() {
- setUp(CliConfigSetSubCommand.class);
+ @Override
+ protected Class<?> getCommandClass() {
+ return CliConfigSetSubCommand.class;
}
@Test
@@ -42,10 +42,11 @@ class CliConfigSetSubCommandTest extends CliCommandTestBase {
// When executed without arguments
execute();
- // Then
- assertThat(err.toString()).contains("Missing required parameter");
- // And
- assertThat(out.toString()).isEmpty();
+ assertAll(
+ () -> assertExitCodeIs(2),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Missing required parameter")
+ );
}
@Test
@@ -54,10 +55,11 @@ class CliConfigSetSubCommandTest extends CliCommandTestBase {
// When executed with key
execute("ignite.cluster-url");
- // Then
- assertThat(err.toString()).contains("should be in KEY=VALUE format but was ignite.cluster-url");
- // And
- assertThat(out.toString()).isEmpty();
+ assertAll(
+ () -> assertExitCodeIs(2),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("should be in KEY=VALUE format but was ignite.cluster-url")
+ );
}
@Test
@@ -66,12 +68,12 @@ class CliConfigSetSubCommandTest extends CliCommandTestBase {
// When executed with key
execute("ignite.cluster-url=test");
- // Then
- assertThat(out.toString()).isEmpty();
- // And
- assertThat(err.toString()).isEmpty();
- // And
- assertThat(config.getProperty("ignite.cluster-url")).isEqualTo("test");
+ assertAll(
+ this::assertExitCodeIsZero,
+ this::assertOutputIsEmpty,
+ this::assertErrOutputIsEmpty,
+ () -> assertThat(config.getProperty("ignite.cluster-url")).isEqualTo("test")
+ );
}
@Test
@@ -80,13 +82,12 @@ class CliConfigSetSubCommandTest extends CliCommandTestBase {
// When executed with multiple keys
execute("ignite.cluster-url=test", "ignite.jdbc-url=test2");
- // Then
- assertThat(out.toString()).isEmpty();
- // And
- assertThat(err.toString()).isEmpty();
- // And
- assertThat(config.getProperty("ignite.cluster-url")).isEqualTo("test");
- // And
- assertThat(config.getProperty("ignite.jdbc-url")).isEqualTo("test2");
+ assertAll(
+ this::assertExitCodeIsZero,
+ this::assertOutputIsEmpty,
+ this::assertErrOutputIsEmpty,
+ () -> assertThat(config.getProperty("ignite.cluster-url")).isEqualTo("test"),
+ () -> assertThat(config.getProperty("ignite.jdbc-url")).isEqualTo("test2")
+ );
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommandTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommandTest.java
index a1fab8055..635badfc1 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommandTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/CliConfigSubCommandTest.java
@@ -17,31 +17,30 @@
package org.apache.ignite.cli.commands.cliconfig;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
import org.apache.ignite.cli.commands.CliCommandTestBase;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
class CliConfigSubCommandTest extends CliCommandTestBase {
- @BeforeEach
- void setUp() {
- setUp(CliConfigSubCommand.class);
+ @Override
+ protected Class<?> getCommandClass() {
+ return CliConfigSubCommand.class;
}
@Test
@DisplayName("Displays all keys")
void noKey() {
- // When executed without arguments
execute();
- // Then
String expectedResult = "ignite.cluster-url=test_cluster_url" + System.lineSeparator()
+ "ignite.jdbc-url=test_jdbc_url" + System.lineSeparator();
- assertThat(out.toString()).isEqualTo(expectedResult);
- // And
- assertThat(err.toString()).isEmpty();
+ assertAll(
+ this::assertExitCodeIsZero,
+ () -> assertOutputIs(expectedResult),
+ this::assertErrOutputIsEmpty
+ );
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/configuration/ShowConfigSubCommandTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/configuration/ShowConfigSubCommandTest.java
deleted file mode 100644
index fbaf927b0..000000000
--- a/modules/cli/src/test/java/org/apache/ignite/cli/commands/configuration/ShowConfigSubCommandTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cli.commands.configuration;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.ignite.cli.commands.CliCommandTestBase;
-import org.apache.ignite.cli.commands.configuration.node.NodeConfigShowSubCommand;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-class ShowConfigSubCommandTest extends CliCommandTestBase {
-
- @BeforeEach
- void setUp() {
- setUp(NodeConfigShowSubCommand.class);
- }
-
- @Disabled("Cluster-url has a default value")
- @Test
- @DisplayName("Cluster-url is mandatory option")
- void mandatoryOptions() {
- // When execute without --cluster-url
- execute();
-
- // Then
- assertThat(err.toString()).contains("Missing required option: '--cluster-url=<clusterUrl>'");
- // And
- assertThat(out.toString()).isEmpty();
- }
-}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/sql/SqlCommandTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/sql/SqlCommandTest.java
new file mode 100644
index 000000000..5093a5fb2
--- /dev/null
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/sql/SqlCommandTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cli.commands.sql;
+
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+import org.apache.ignite.cli.commands.CliCommandTestBase;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+class SqlCommandTest extends CliCommandTestBase {
+
+ @Override
+ protected Class<?> getCommandClass() {
+ return SqlCommand.class;
+ }
+
+ @Test
+ @DisplayName("Should throw error if executed without --execute or --script-file options")
+ void withoutOptions() {
+ execute("--jdbc-url=");
+
+ assertAll(
+ () -> assertExitCodeIs(2),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("Missing required argument (specify one of these): (-e=<command> | -f=<file>)")
+ );
+ }
+
+ @Test
+ @DisplayName("Should throw error if both --execute or --script-file options are present")
+ void mutuallyExclusiveOptions() {
+ execute("--jdbc-url=", "--execute=", "--script-file=");
+
+ assertAll(
+ () -> assertExitCodeIs(2),
+ this::assertOutputIsEmpty,
+ () -> assertErrOutputContains("--execute=<command>, --script-file=<file> are mutually exclusive (specify only one)")
+ );
+ }
+}