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/08/11 15:53:43 UTC
[ignite-3] branch main updated: IGNITE-17110 Auto-connect on the REPL start. Fixes #984
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 ddb656486 IGNITE-17110 Auto-connect on the REPL start. Fixes #984
ddb656486 is described below
commit ddb656486460dcdadbc637cac87075fb69fbd0fd
Author: Vadim Pakhnushev <86...@users.noreply.github.com>
AuthorDate: Thu Aug 11 18:53:24 2022 +0300
IGNITE-17110 Auto-connect on the REPL start. Fixes #984
Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
.../org/apache/ignite/cli/IntegrationTestBase.java | 2 +-
...liCommandTestNotInitializedIntegrationBase.java | 10 +-
.../commands/questions/ItConnectToClusterTest.java | 141 +++++++++++++++++++++
.../src/main/java/org/apache/ignite/cli/Main.java | 4 +
.../profile/CliConfigCreateProfileCall.java | 2 +-
.../ignite/cli/call/connect/ConnectCall.java | 8 +-
.../questions/ConnectToClusterQuestion.java | 45 ++++++-
...Profile.java => CachedStateConfigProvider.java} | 24 ++--
.../cli/config/{Profile.java => Config.java} | 38 +++++-
.../apache/ignite/cli/config/ConfigConstants.java | 1 +
.../ignite/cli/config/ConfigManagerProvider.java | 5 +
.../java/org/apache/ignite/cli/config/Profile.java | 62 ++++++++-
.../org/apache/ignite/cli/config/StateConfig.java | 61 +++++++++
...nagerProvider.java => StateConfigProvider.java} | 11 +-
.../ignite/cli/config/StateFolderProvider.java | 5 +-
.../config/ini/{IniProfile.java => IniConfig.java} | 24 ++--
.../ignite/cli/config/ini/IniConfigManager.java | 21 +--
.../org/apache/ignite/cli/config/ini/IniFile.java | 33 ++++-
.../apache/ignite/cli/config/ini/IniParser.java | 8 +-
.../apache/ignite/cli/config/ini/IniProfile.java | 40 +-----
.../apache/ignite/cli/config/ini/IniSection.java | 5 -
.../apache/ignite/cli/core/flow/builder/Flows.java | 2 +-
.../java/org/apache/ignite/cli/core/repl/Repl.java | 11 +-
.../apache/ignite/cli/core/repl/ReplBuilder.java | 10 +-
.../cli/core/repl/executor/ReplExecutor.java | 5 +-
.../cliconfig/TestConfigManagerHelper.java | 32 +++--
.../ignite/cli/config/TestStateConfigHelper.java} | 27 ++--
.../cli/config/TestStateConfigProvider.java} | 25 ++--
.../src/test/resources/cluster_url_non_default.ini | 5 +
.../src/test/resources/last_connected_default.ini | 1 +
30 files changed, 515 insertions(+), 153 deletions(-)
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/IntegrationTestBase.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/IntegrationTestBase.java
index 13f036e3b..2c243b063 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/IntegrationTestBase.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/IntegrationTestBase.java
@@ -67,7 +67,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
*/
@ExtendWith(WorkDirectoryExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-@MicronautTest
+@MicronautTest(rebuildContext = true)
public class IntegrationTestBase extends BaseIgniteAbstractTest {
public static final int DEFAULT_NODES_COUNT = 3;
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestNotInitializedIntegrationBase.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestNotInitializedIntegrationBase.java
index 4012df058..f82648d8c 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestNotInitializedIntegrationBase.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/CliCommandTestNotInitializedIntegrationBase.java
@@ -30,6 +30,7 @@ import org.apache.ignite.cli.commands.cliconfig.TestConfigManagerHelper;
import org.apache.ignite.cli.commands.cliconfig.TestConfigManagerProvider;
import org.apache.ignite.cli.config.ConfigDefaultValueProvider;
import org.apache.ignite.cli.config.ini.IniConfigManager;
+import org.apache.ignite.cli.core.repl.context.CommandLineContextProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -43,12 +44,16 @@ import picocli.CommandLine;
public class CliCommandTestNotInitializedIntegrationBase extends IntegrationTestBase {
/** Correct ignite jdbc url. */
protected static final String JDBC_URL = "jdbc:ignite:thin://127.0.0.1:10800";
+
@Inject
- ConfigDefaultValueProvider configDefaultValueProvider;
+ private ConfigDefaultValueProvider configDefaultValueProvider;
+
@Inject
- TestConfigManagerProvider configManagerProvider;
+ protected TestConfigManagerProvider configManagerProvider;
+
@Inject
private ApplicationContext context;
+
private CommandLine cmd;
private StringWriter sout;
@@ -73,6 +78,7 @@ public class CliCommandTestNotInitializedIntegrationBase extends IntegrationTest
serr = new StringWriter();
cmd.setOut(new PrintWriter(sout));
cmd.setErr(new PrintWriter(serr));
+ CommandLineContextProvider.setCmd(cmd);
}
@BeforeAll
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/questions/ItConnectToClusterTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/questions/ItConnectToClusterTest.java
new file mode 100644
index 000000000..4b5451a52
--- /dev/null
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/commands/questions/ItConnectToClusterTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.questions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+import jakarta.inject.Inject;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.apache.ignite.cli.commands.CliCommandTestInitializedIntegrationBase;
+import org.apache.ignite.cli.commands.cliconfig.TestConfigManagerHelper;
+import org.apache.ignite.cli.config.ConfigConstants;
+import org.apache.ignite.cli.config.TestStateConfigHelper;
+import org.apache.ignite.cli.config.TestStateConfigProvider;
+import org.apache.ignite.cli.config.ini.IniConfigManager;
+import org.apache.ignite.cli.core.flow.question.JlineQuestionWriterReader;
+import org.apache.ignite.cli.core.flow.question.QuestionAskerFactory;
+import org.apache.ignite.cli.core.repl.prompt.PromptProvider;
+import org.jline.reader.impl.LineReaderImpl;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.impl.DumbTerminal;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import picocli.CommandLine.Help.Ansi;
+
+class ItConnectToClusterTest extends CliCommandTestInitializedIntegrationBase {
+ @Inject
+ private PromptProvider promptProvider;
+
+ @Inject
+ private TestStateConfigProvider stateConfigProvider;
+
+ @Inject
+ private ConnectToClusterQuestion question;
+
+ private Terminal terminal;
+ private Path input;
+
+ @BeforeEach
+ public void setUp(TestInfo testInfo) throws Exception {
+ super.setUp(testInfo);
+
+ input = Files.createTempFile("input", "");
+ input.toFile().deleteOnExit();
+ terminal = new DumbTerminal(Files.newInputStream(input), new FileOutputStream(FileDescriptor.out));
+ LineReaderImpl reader = new LineReaderImpl(terminal);
+ QuestionAskerFactory.setReadWriter(new JlineQuestionWriterReader(reader));
+ }
+
+ @AfterEach
+ public void cleanUp() throws IOException {
+ terminal.input().close();
+ terminal.close();
+ }
+
+ @Test
+ @DisplayName("Should connect to last connected cluster url")
+ void connectOnStart() throws IOException {
+ // Given prompt before connect
+ String promptBefore = Ansi.OFF.string(promptProvider.getPrompt());
+ assertThat(promptBefore).isEqualTo("[disconnected]> ");
+
+ // And last connected URL is equal to the default URL
+ stateConfigProvider.config = TestStateConfigHelper.createLastConnectedDefault();
+
+ // And answer to the first question is "y"
+ bindAnswers("y");
+
+ // When asked the question
+ question.askQuestionOnReplStart();
+
+ // Then
+ assertAll(
+ this::assertErrOutputIsEmpty,
+ () -> assertOutputContains("Connected to http://localhost:10300")
+ );
+ // And prompt is changed to connect
+ String promptAfter = Ansi.OFF.string(promptProvider.getPrompt());
+ assertThat(promptAfter).isEqualTo("[" + nodeName() + "]> ");
+ }
+
+ @Test
+ @DisplayName("Should connect to last connected cluster url and ask for save")
+ void connectOnStartAndSave() throws IOException {
+ // Given prompt before connect
+ String promptBefore = Ansi.OFF.string(promptProvider.getPrompt());
+ assertThat(promptBefore).isEqualTo("[disconnected]> ");
+
+ // And last connected URL is not equal to the default URL
+ configManagerProvider.configManager = new IniConfigManager(TestConfigManagerHelper.createClusterUrlNonDefault());
+ stateConfigProvider.config = TestStateConfigHelper.createLastConnectedDefault();
+
+ // And answer to both questions is "y"
+ bindAnswers("y", "y");
+
+ // When asked the questions
+ question.askQuestionOnReplStart();
+
+ // Then
+ assertAll(
+ this::assertErrOutputIsEmpty,
+ () -> assertOutputContains("Connected to http://localhost:10300"),
+ () -> assertOutputContains("Config saved")
+ );
+ // And prompt is changed to connect
+ String promptAfter = Ansi.OFF.string(promptProvider.getPrompt());
+ assertThat(promptAfter).isEqualTo("[" + nodeName() + "]> ");
+ assertThat(configManagerProvider.get().getCurrentProperty(ConfigConstants.CLUSTER_URL))
+ .isEqualTo("http://localhost:10300");
+ }
+
+ private String nodeName() {
+ return CLUSTER_NODES.get(0).name();
+ }
+
+ private void bindAnswers(String... answers) throws IOException {
+ Files.writeString(input, String.join("\n", answers) + "\n");
+ }
+}
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 dac94907d..57a17cb0d 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
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.stream.Collectors;
import org.apache.ignite.cli.commands.TopLevelCliCommand;
import org.apache.ignite.cli.commands.TopLevelCliReplCommand;
+import org.apache.ignite.cli.commands.questions.ConnectToClusterQuestion;
import org.apache.ignite.cli.config.ConfigDefaultValueProvider;
import org.apache.ignite.cli.core.call.CallExecutionPipeline;
import org.apache.ignite.cli.core.call.StringCallInput;
@@ -92,6 +93,8 @@ public class Main {
VersionProvider versionProvider = micronautFactory.create(VersionProvider.class);
System.out.println(banner(versionProvider));
+ ConnectToClusterQuestion question = micronautFactory.create(ConnectToClusterQuestion.class);
+
replExecutorProvider.get().execute(Repl.builder()
.withPromptProvider(micronautFactory.create(PromptProvider.class))
.withAliases(aliases)
@@ -105,6 +108,7 @@ public class Main {
.exceptionHandlers(new DefaultExceptionHandlers())
.exceptionHandlers(exceptionHandlers)
.build())
+ .withOnStart(question::askQuestionOnReplStart)
.withHistoryFileName("history")
.withTailTipWidgets()
.build());
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/cliconfig/profile/CliConfigCreateProfileCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/cliconfig/profile/CliConfigCreateProfileCall.java
index 685fc4f5c..e76d83635 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/call/cliconfig/profile/CliConfigCreateProfileCall.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/cliconfig/profile/CliConfigCreateProfileCall.java
@@ -47,7 +47,7 @@ public class CliConfigCreateProfileCall implements Call<CliConfigCreateProfileCa
Profile newProfile = configManager.createProfile(profileName);
if (copyFrom != null) {
- newProfile.setProperties(copyFrom);
+ newProfile.setProperties(copyFrom.getAll());
}
if (input.isActivate()) {
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 675dd24e6..bf72de775 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
@@ -21,6 +21,8 @@ import com.google.gson.Gson;
import jakarta.inject.Singleton;
import java.net.MalformedURLException;
import java.net.URL;
+import org.apache.ignite.cli.config.ConfigConstants;
+import org.apache.ignite.cli.config.StateConfigProvider;
import org.apache.ignite.cli.core.call.Call;
import org.apache.ignite.cli.core.call.CallOutput;
import org.apache.ignite.cli.core.call.DefaultCallOutput;
@@ -41,8 +43,11 @@ public class ConnectCall implements Call<ConnectCallInput, String> {
private final Session session;
- public ConnectCall(Session session) {
+ private final StateConfigProvider stateConfigProvider;
+
+ public ConnectCall(Session session, StateConfigProvider stateConfigProvider) {
this.session = session;
+ this.stateConfigProvider = stateConfigProvider;
}
@Override
@@ -50,6 +55,7 @@ public class ConnectCall implements Call<ConnectCallInput, String> {
try {
String nodeUrl = input.getNodeUrl();
session.setNodeUrl(nodeUrl);
+ stateConfigProvider.get().setProperty(ConfigConstants.LAST_CONNECTED_URL, nodeUrl);
session.setNodeName(fetchNodeName(input));
String configuration = fetchNodeConfiguration(input);
session.setJdbcUrl(constructJdbcUrl(configuration, nodeUrl));
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/questions/ConnectToClusterQuestion.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/questions/ConnectToClusterQuestion.java
index 81dc6ac54..5c3a6496e 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/questions/ConnectToClusterQuestion.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/questions/ConnectToClusterQuestion.java
@@ -24,6 +24,7 @@ import org.apache.ignite.cli.call.connect.ConnectCall;
import org.apache.ignite.cli.call.connect.ConnectCallInput;
import org.apache.ignite.cli.config.ConfigConstants;
import org.apache.ignite.cli.config.ConfigManagerProvider;
+import org.apache.ignite.cli.config.StateConfigProvider;
import org.apache.ignite.cli.core.flow.Flowable;
import org.apache.ignite.cli.core.flow.builder.FlowBuilder;
import org.apache.ignite.cli.core.flow.builder.Flows;
@@ -41,7 +42,10 @@ public class ConnectToClusterQuestion {
private ConnectCall connectCall;
@Inject
- private ConfigManagerProvider provider;
+ private ConfigManagerProvider configManagerProvider;
+
+ @Inject
+ private StateConfigProvider stateConfigProvider;
@Inject
private Session session;
@@ -54,13 +58,13 @@ public class ConnectToClusterQuestion {
* @return {@link FlowBuilder} instance with question in case when cluster url.
*/
public FlowBuilder<Void, String> askQuestionIfNotConnected(String clusterUrl) {
- String clusterProperty = provider.get().getCurrentProperty(ConfigConstants.CLUSTER_URL);
+ String defaultUrl = configManagerProvider.get().getCurrentProperty(ConfigConstants.CLUSTER_URL);
String question = "You are not connected to node. Do you want to connect to the default node "
- + clusterProperty + " ? [Y/n] ";
+ + defaultUrl + " ? [Y/n] ";
return Flows.from(clusterUrlOrSessionNode(clusterUrl))
.ifThen(Objects::isNull, Flows.<String, ConnectCallInput>acceptQuestion(question,
- () -> new ConnectCallInput(clusterProperty))
+ () -> new ConnectCallInput(defaultUrl))
.then(Flows.fromCall(connectCall))
.toOutput(CommandLineContextProvider.getContext())
.build())
@@ -70,4 +74,37 @@ public class ConnectToClusterQuestion {
private String clusterUrlOrSessionNode(String clusterUrl) {
return clusterUrl != null ? clusterUrl : session.nodeUrl();
}
+
+ /**
+ * Ask for connect to the cluster and suggest to save the last connected URL as default.
+ */
+ public void askQuestionOnReplStart() {
+ String defaultUrl = configManagerProvider.get().getCurrentProperty(ConfigConstants.CLUSTER_URL);
+ String lastConnectedUrl = stateConfigProvider.get().getProperty(ConfigConstants.LAST_CONNECTED_URL);
+ String question;
+ String clusterUrl;
+ if (lastConnectedUrl != null) {
+ question = "Do you want to connect to the last connected node " + lastConnectedUrl + " ? [Y/n]";
+ clusterUrl = lastConnectedUrl;
+ } else {
+ question = "Do you want to connect to the default node " + defaultUrl + " ? [Y/n]";
+ clusterUrl = defaultUrl;
+ }
+
+ Flows.acceptQuestion(question, () -> new ConnectCallInput(clusterUrl))
+ .then(Flows.fromCall(connectCall))
+ .toOutput(CommandLineContextProvider.getContext())
+ .ifThen(s -> !Objects.equals(lastConnectedUrl, defaultUrl) && session.isConnectedToNode(),
+ defaultUrlQuestion(lastConnectedUrl).toOutput(CommandLineContextProvider.getContext()).build())
+ .build().start(Flowable.empty());
+ }
+
+ private FlowBuilder<String, String> defaultUrlQuestion(String lastConnectedUrl) {
+ return Flows.acceptQuestion("Would you like to use " + lastConnectedUrl + " as the default URL? [Y/n]",
+ () -> {
+ configManagerProvider.get().setProperty(ConfigConstants.CLUSTER_URL, lastConnectedUrl);
+ return "Config saved";
+ }
+ );
+ }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/CachedStateConfigProvider.java
similarity index 65%
copy from modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
copy to modules/cli/src/main/java/org/apache/ignite/cli/config/CachedStateConfigProvider.java
index 31d47a5fb..4caaf0375 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/CachedStateConfigProvider.java
@@ -17,23 +17,19 @@
package org.apache.ignite.cli.config;
-import java.util.Map;
+import jakarta.inject.Singleton;
/**
- * Ignite CLI Profile.
+ * Implementation of {@link StateConfigProvider} based on the ini file in the state folder.
*/
-public interface Profile {
- String getName();
+@Singleton
+public class CachedStateConfigProvider implements StateConfigProvider {
+ private static final String CONFIG_FILE_NAME = "config.ini";
- Map<String, String> getAll();
+ private final Config config = StateConfig.getStateConfig(StateFolderProvider.getStateFile(CONFIG_FILE_NAME));
- String getProperty(String key);
-
- String getProperty(String key, String defaultValue);
-
- void setProperty(String key, String value);
-
- void setProperties(Map<String, String> values);
-
- void setProperties(Profile copyFrom);
+ @Override
+ public Config get() {
+ return config;
+ }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/Config.java
similarity index 59%
copy from modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
copy to modules/cli/src/main/java/org/apache/ignite/cli/config/Config.java
index 31d47a5fb..cc9e078a3 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/Config.java
@@ -20,20 +20,46 @@ package org.apache.ignite.cli.config;
import java.util.Map;
/**
- * Ignite CLI Profile.
+ * Ignite CLI config.
*/
-public interface Profile {
- String getName();
-
+public interface Config {
+ /**
+ * Gets all properties.
+ *
+ * @return all properties
+ */
Map<String, String> getAll();
+ /**
+ * Gets a property.
+ *
+ * @param key property to get
+ * @return property value or {@code null} if config doesn't contain this property
+ */
String getProperty(String key);
+ /**
+ * Gets a property.
+ *
+ * @param key property to get
+ * @param defaultValue default value of the property
+ *
+ * @return property value or {@code defaultValue} if config doesn't contain this property
+ */
String getProperty(String key, String defaultValue);
+ /**
+ * Sets a property.
+ *
+ * @param key property to set
+ * @param value value to set
+ */
void setProperty(String key, String value);
+ /**
+ * Sets properties to this profile.
+ *
+ * @param values map of properties to set
+ */
void setProperties(Map<String, String> values);
-
- void setProperties(Profile copyFrom);
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigConstants.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigConstants.java
index d8ce17083..cf8912157 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigConstants.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigConstants.java
@@ -31,6 +31,7 @@ public final class ConfigConstants {
public static final String CURRENT_PROFILE = "current_profile";
public static final String CLUSTER_URL = "ignite.cluster-endpoint-url";
public static final String JDBC_URL = "ignite.jdbc-url";
+ public static final String LAST_CONNECTED_URL = "ignite.last-connected-url";
private ConfigConstants() {
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java
index 921e65138..c7fe47923 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java
@@ -21,5 +21,10 @@ package org.apache.ignite.cli.config;
* Provider for {@link ConfigManager}.
*/
public interface ConfigManagerProvider {
+ /**
+ * Gets the CLI config manager.
+ *
+ * @return config manager
+ */
ConfigManager get();
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
index 31d47a5fb..24036e9dc 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
@@ -23,17 +23,67 @@ import java.util.Map;
* Ignite CLI Profile.
*/
public interface Profile {
+ /**
+ * Gets name of the profile.
+ *
+ * @return profile name
+ */
String getName();
- Map<String, String> getAll();
+ /**
+ * Gets a {@link Config} stored in this profile.
+ *
+ * @return config
+ */
+ Config getConfig();
- String getProperty(String key);
+ /**
+ * Convenience method to get all properties from this profile.
+ *
+ * @return map of all properties
+ */
+ default Map<String, String> getAll() {
+ return getConfig().getAll();
+ }
- String getProperty(String key, String defaultValue);
+ /**
+ * Convenience method to get a property from this profile.
+ *
+ * @param key property to get
+ * @return property value or {@code null} if config doesn't contain this property
+ */
+ default String getProperty(String key) {
+ return getConfig().getProperty(key);
+ }
- void setProperty(String key, String value);
+ /**
+ * Convenience method to get a property from this profile.
+ *
+ * @param key property to get
+ * @param defaultValue default value of the property
+ *
+ * @return property value or {@code defaultValue} if config doesn't contain this property
+ */
+ default String getProperty(String key, String defaultValue) {
+ return getConfig().getProperty(key, defaultValue);
+ }
- void setProperties(Map<String, String> values);
+ /**
+ * Convenience method to set a property to this profile.
+ *
+ * @param key property to set
+ * @param value value to set
+ */
+ default void setProperty(String key, String value) {
+ getConfig().setProperty(key, value);
+ }
- void setProperties(Profile copyFrom);
+ /**
+ * Convenience method to set properties to this profile.
+ *
+ * @param values map of properties to set
+ */
+ default void setProperties(Map<String, String> values) {
+ getConfig().setProperties(values);
+ }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/StateConfig.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/StateConfig.java
new file mode 100644
index 000000000..16dfba036
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/StateConfig.java
@@ -0,0 +1,61 @@
+/*
+ * 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.config;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.ignite.cli.config.ini.IniConfig;
+import org.apache.ignite.cli.config.ini.IniFile;
+
+/**
+ * Config file which stores information between application restarts, but not part of the config.
+ */
+public class StateConfig {
+
+ /**
+ * Returns an instance of {@link Config} holding the properties.
+ *
+ * @param file INI file.
+ * @return new instance of {@link Config}
+ */
+ public static Config getStateConfig(File file) {
+ IniFile iniFile = loadStateConfig(file);
+ return new IniConfig(iniFile.getTopLevelSection(), iniFile::store);
+ }
+
+ private static IniFile loadStateConfig(File file) {
+ try {
+ return new IniFile(file);
+ } catch (IOException e) {
+ return createDefaultConfig(file);
+ }
+ }
+
+ private static IniFile createDefaultConfig(File file) {
+ try {
+ file.getParentFile().mkdirs();
+ file.delete();
+ file.createNewFile();
+ IniFile ini = new IniFile(file);
+ ini.store();
+ return ini;
+ } catch (IOException e) {
+ throw new ConfigInitializationException(file.getAbsolutePath(), e);
+ }
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/StateConfigProvider.java
similarity index 80%
copy from modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java
copy to modules/cli/src/main/java/org/apache/ignite/cli/config/StateConfigProvider.java
index 921e65138..db0a07b74 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ConfigManagerProvider.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/StateConfigProvider.java
@@ -18,8 +18,13 @@
package org.apache.ignite.cli.config;
/**
- * Provider for {@link ConfigManager}.
+ * Provider for the application state config.
*/
-public interface ConfigManagerProvider {
- ConfigManager get();
+public interface StateConfigProvider {
+ /**
+ * Gets the application state config.
+ *
+ * @return application state config
+ */
+ Config get();
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/StateFolderProvider.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/StateFolderProvider.java
index 021cd93b5..24d408a4d 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/StateFolderProvider.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/StateFolderProvider.java
@@ -28,7 +28,6 @@ public final class StateFolderProvider {
private static final String PARENT_FOLDER_NAME = "ignitecli";
private StateFolderProvider() {
-
}
/**
@@ -36,8 +35,8 @@ public final class StateFolderProvider {
*
* @return Folder for state storage.
*/
- public static File getStateFolder() {
- return getStateRoot().resolve(PARENT_FOLDER_NAME).toFile();
+ public static File getStateFile(String name) {
+ return getStateRoot().resolve(PARENT_FOLDER_NAME).resolve(name).toFile();
}
private static Path getStateRoot() {
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfig.java
similarity index 79%
copy from modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java
copy to modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfig.java
index dcda97307..8d8e2ed21 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfig.java
@@ -18,55 +18,49 @@
package org.apache.ignite.cli.config.ini;
import java.util.Map;
-import org.apache.ignite.cli.config.Profile;
+import org.apache.ignite.cli.config.Config;
/**
- * Implementation of {@link Profile} based on {@link IniSection}.
+ * Implementation of {@link Config} based on {@link IniSection}.
*/
-public class IniProfile implements Profile {
+public class IniConfig implements Config {
private final IniSection section;
private final Runnable saveAction;
- public IniProfile(IniSection section, Runnable saveAction) {
+ public IniConfig(IniSection section, Runnable saveAction) {
this.section = section;
this.saveAction = saveAction;
}
- @Override
- public String getName() {
- return section.getName();
- }
-
+ /** {@inheritDoc} */
@Override
public Map<String, String> getAll() {
return section.getAll();
}
+ /** {@inheritDoc} */
@Override
public String getProperty(String key) {
return section.getProperty(key);
}
+ /** {@inheritDoc} */
@Override
public String getProperty(String key, String defaultValue) {
return section.getProperty(key, defaultValue);
}
+ /** {@inheritDoc} */
@Override
public void setProperty(String key, String value) {
section.setProperty(key, value);
saveAction.run();
}
+ /** {@inheritDoc} */
@Override
public void setProperties(Map<String, String> values) {
section.setProperties(values);
saveAction.run();
}
-
- @Override
- public void setProperties(Profile copyFrom) {
- section.setProperties(copyFrom);
- saveAction.run();
- }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfigManager.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfigManager.java
index bba9f1739..685f9bc53 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfigManager.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniConfigManager.java
@@ -24,7 +24,6 @@ import static org.apache.ignite.cli.config.ConfigConstants.JDBC_URL;
import java.io.File;
import java.io.IOException;
import java.util.NoSuchElementException;
-import org.apache.ignite.cli.config.ConfigConstants;
import org.apache.ignite.cli.config.ConfigInitializationException;
import org.apache.ignite.cli.config.ConfigManager;
import org.apache.ignite.cli.config.Profile;
@@ -56,7 +55,7 @@ public class IniConfigManager implements ConfigManager {
findCurrentProfile(configFile);
} catch (IOException | NoSuchElementException e) {
log.warn("User config is corrupted or doesn't exist.", e);
- configFile = createDefaultConfig();
+ configFile = createDefaultConfig(file);
}
this.configFile = configFile;
this.currentProfileName = findCurrentProfile(configFile).getProperty(CURRENT_PROFILE);
@@ -65,7 +64,10 @@ public class IniConfigManager implements ConfigManager {
private static IniSection findCurrentProfile(IniFile configFile) {
IniSection internalSection = configFile.getSection(INTERNAL_SECTION_NAME);
if (internalSection == null) {
- IniSection section = configFile.getSections().stream().findFirst().orElseThrow();
+ IniSection section = configFile.getSections().stream()
+ .filter(s -> !s.getName().equals(IniParser.NO_SECTION)) // Don't use top-level section
+ .findFirst()
+ .orElseThrow();
internalSection = configFile.createSection(INTERNAL_SECTION_NAME);
internalSection.setProperty(CURRENT_PROFILE, section.getName());
}
@@ -102,13 +104,12 @@ public class IniConfigManager implements ConfigManager {
configFile.store();
}
- private static IniFile createDefaultConfig() {
- File configFile = ConfigConstants.getConfigFile();
+ private static IniFile createDefaultConfig(File file) {
try {
- configFile.getParentFile().mkdirs();
- configFile.delete();
- configFile.createNewFile();
- IniFile ini = new IniFile(configFile);
+ file.getParentFile().mkdirs();
+ file.delete();
+ file.createNewFile();
+ IniFile ini = new IniFile(file);
IniSection internal = ini.createSection(INTERNAL_SECTION_NAME);
internal.setProperty("current_profile", "default");
IniSection defaultSection = ini.createSection("default");
@@ -117,7 +118,7 @@ public class IniConfigManager implements ConfigManager {
ini.store();
return ini;
} catch (IOException e) {
- throw new ConfigInitializationException(configFile.getAbsolutePath(), e);
+ throw new ConfigInitializationException(file.getAbsolutePath(), e);
}
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniFile.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniFile.java
index 6dce2340b..6948aa10c 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniFile.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniFile.java
@@ -51,6 +51,15 @@ public class IniFile {
return content.get(name);
}
+ /**
+ * Returns properties stored outside any section.
+ *
+ * @return top-level section
+ */
+ public IniSection getTopLevelSection() {
+ return getSection(IniParser.NO_SECTION);
+ }
+
public Collection<IniSection> getSections() {
return content.values();
}
@@ -68,19 +77,31 @@ public class IniFile {
private void store(OutputStream outputStream) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
+
+ // Write top-level properties first
+ IniSection topLevelSection = getTopLevelSection();
+ if (topLevelSection != null) {
+ writeSection(bufferedWriter, topLevelSection);
+ }
for (IniSection section : getSections()) {
- bufferedWriter.write("[" + section.getName() + "]");
- bufferedWriter.newLine();
- for (Map.Entry<String, String> sectionEntry : section.getAll().entrySet()) {
- bufferedWriter.write(sectionEntry.getKey() + " = ");
- bufferedWriter.write(sectionEntry.getValue());
+ if (section != topLevelSection) {
+ bufferedWriter.write("[" + section.getName() + "]");
bufferedWriter.newLine();
+ writeSection(bufferedWriter, section);
}
- bufferedWriter.newLine();
}
bufferedWriter.flush();
}
+ private void writeSection(BufferedWriter bufferedWriter, IniSection section) throws IOException {
+ for (Map.Entry<String, String> sectionEntry : section.getAll().entrySet()) {
+ bufferedWriter.write(sectionEntry.getKey() + " = ");
+ bufferedWriter.write(sectionEntry.getValue());
+ bufferedWriter.newLine();
+ }
+ bufferedWriter.newLine();
+ }
+
/**
* Create and return new {@link IniSection} with provided name.
*
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniParser.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniParser.java
index c0eb2bb92..fd475040b 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniParser.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniParser.java
@@ -33,6 +33,11 @@ import java.util.regex.Pattern;
* INI file parser.
*/
public class IniParser {
+ /**
+ * Section name for properties outside any section.
+ */
+ public static final String NO_SECTION = "NO_SECTION";
+
private static final Pattern SECTION_PATTERN = Pattern.compile("\\s*\\[([^]]*)\\]\\s*");
private static final Pattern KEY_VALUE_PATTER = Pattern.compile("\\s*([^=]*)=(.*)");
private static final Pattern COMMENT_LINE = Pattern.compile("^[;|#].*");
@@ -70,7 +75,8 @@ public class IniParser {
private Map<String, IniSection> parseIniFile(BufferedReader bufferedReader) throws IOException {
Map<String, IniSection> map = new LinkedHashMap<>();
- IniSection currentSection = new IniSection("NO_SECTION");
+ IniSection currentSection = new IniSection(NO_SECTION);
+ map.put(NO_SECTION, currentSection);
String line;
while ((line = bufferedReader.readLine()) != null) {
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java
index dcda97307..127f820d8 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniProfile.java
@@ -17,7 +17,7 @@
package org.apache.ignite.cli.config.ini;
-import java.util.Map;
+import org.apache.ignite.cli.config.Config;
import org.apache.ignite.cli.config.Profile;
/**
@@ -25,48 +25,22 @@ import org.apache.ignite.cli.config.Profile;
*/
public class IniProfile implements Profile {
private final IniSection section;
- private final Runnable saveAction;
+ private final IniConfig config;
public IniProfile(IniSection section, Runnable saveAction) {
this.section = section;
- this.saveAction = saveAction;
+ this.config = new IniConfig(section, saveAction);
}
+ /** {@inheritDoc} */
@Override
public String getName() {
return section.getName();
}
+ /** {@inheritDoc} */
@Override
- public Map<String, String> getAll() {
- return section.getAll();
- }
-
- @Override
- public String getProperty(String key) {
- return section.getProperty(key);
- }
-
- @Override
- public String getProperty(String key, String defaultValue) {
- return section.getProperty(key, defaultValue);
- }
-
- @Override
- public void setProperty(String key, String value) {
- section.setProperty(key, value);
- saveAction.run();
- }
-
- @Override
- public void setProperties(Map<String, String> values) {
- section.setProperties(values);
- saveAction.run();
- }
-
- @Override
- public void setProperties(Profile copyFrom) {
- section.setProperties(copyFrom);
- saveAction.run();
+ public Config getConfig() {
+ return config;
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniSection.java b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniSection.java
index eb6d95b70..c55c428de 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniSection.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/config/ini/IniSection.java
@@ -20,7 +20,6 @@ package org.apache.ignite.cli.config.ini;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
-import org.apache.ignite.cli.config.Profile;
/**
* INI section representation.
@@ -56,8 +55,4 @@ public class IniSection {
public void setProperties(Map<String, String> values) {
props.putAll(values);
}
-
- public void setProperties(Profile copyFrom) {
- props.putAll(copyFrom.getAll());
- }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/flow/builder/Flows.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/flow/builder/Flows.java
index 69c59caeb..af6283601 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/flow/builder/Flows.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/flow/builder/Flows.java
@@ -110,7 +110,7 @@ public final class Flows {
}
/**
- * Create new {@link FlowBuilder} which started from question.
+ * Create new {@link FlowBuilder} which starts from question.
*
* @param question question text.
* @param answers all possible answers.
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/Repl.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/Repl.java
index 78e0f7fd5..97fc65886 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/Repl.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/Repl.java
@@ -51,6 +51,8 @@ public class Repl {
private final boolean tailTipWidgetsEnabled;
+ private final Runnable onStart;
+
/**
* Constructor.
*
@@ -63,6 +65,7 @@ public class Repl {
* @param completer completer instance.
* @param historyFileName file name for storing commands history.
* @param tailTipWidgetsEnabled whether tailtip widgets are enabled.
+ * @param onStart callback that will run when REPL is started.
*/
public Repl(PromptProvider promptProvider,
Class<?> commandClass,
@@ -72,7 +75,8 @@ public class Repl {
CallExecutionPipelineProvider provider,
Completer completer,
String historyFileName,
- boolean tailTipWidgetsEnabled
+ boolean tailTipWidgetsEnabled,
+ Runnable onStart
) {
this.promptProvider = promptProvider;
this.commandClass = commandClass;
@@ -83,6 +87,7 @@ public class Repl {
this.completer = completer;
this.historyFileName = historyFileName;
this.tailTipWidgetsEnabled = tailTipWidgetsEnabled;
+ this.onStart = onStart;
}
/**
@@ -147,4 +152,8 @@ public class Repl {
public boolean isTailTipWidgetsEnabled() {
return tailTipWidgetsEnabled;
}
+
+ public void onStart() {
+ onStart.run();
+ }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/ReplBuilder.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/ReplBuilder.java
index 838a8f076..55855c50f 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/ReplBuilder.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/ReplBuilder.java
@@ -49,6 +49,8 @@ public class ReplBuilder {
private boolean tailTipWidgetsEnabled;
+ private Runnable onStart = () -> {};
+
/**
* Build methods.
*
@@ -64,7 +66,8 @@ public class ReplBuilder {
provider,
completer,
historyFileName,
- tailTipWidgetsEnabled
+ tailTipWidgetsEnabled,
+ onStart
);
}
@@ -127,6 +130,11 @@ public class ReplBuilder {
return this;
}
+ public ReplBuilder withOnStart(Runnable onStart) {
+ this.onStart = onStart;
+ return this;
+ }
+
public ReplBuilder withHistoryFileName(String historyFileName) {
this.historyFileName = historyFileName;
return this;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/ReplExecutor.java b/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/ReplExecutor.java
index d62d63620..b97b9032a 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/ReplExecutor.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/ReplExecutor.java
@@ -17,7 +17,6 @@
package org.apache.ignite.cli.core.repl.executor;
-import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
@@ -96,7 +95,7 @@ public class ReplExecutor {
? new AggregateCompleter(registry.completer(), repl.getCompleter())
: registry.completer());
if (repl.getHistoryFileName() != null) {
- reader.variable(LineReader.HISTORY_FILE, new File(StateFolderProvider.getStateFolder(), repl.getHistoryFileName()));
+ reader.variable(LineReader.HISTORY_FILE, StateFolderProvider.getStateFile(repl.getHistoryFileName()));
}
RegistryCommandExecutor executor = new RegistryCommandExecutor(registry, parser);
@@ -110,6 +109,8 @@ public class ReplExecutor {
QuestionAskerFactory.setReadWriter(new JlineQuestionWriterReader(reader));
+ repl.onStart();
+
while (!interrupted.get()) {
try {
executor.cleanUp();
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/TestConfigManagerHelper.java b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/TestConfigManagerHelper.java
index d4e6ab748..797787f7c 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/TestConfigManagerHelper.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/commands/cliconfig/TestConfigManagerHelper.java
@@ -30,34 +30,46 @@ import org.apache.ignite.cli.config.ConfigManager;
* Test factory for {@link ConfigManager}.
*/
public class TestConfigManagerHelper {
- public static final String EMPTY = "empty.ini";
- public static final String TWO_SECTION_WITH_INTERNAL_PART = "two_section_with_internal.ini";
- public static final String TWO_SECTION_WITHOUT_INTERNAL_PART = "two_section_without_internal.ini";
- public static final String INTEGRATION_TESTS = "integration_tests.ini";
+ private static final String EMPTY = "empty.ini";
+ private static final String TWO_SECTION_WITH_INTERNAL_PART = "two_section_with_internal.ini";
+ private static final String TWO_SECTION_WITHOUT_INTERNAL_PART = "two_section_without_internal.ini";
+ private static final String INTEGRATION_TESTS = "integration_tests.ini";
+
+ private static final String CLUSTER_URL_NON_DEFAULT = "cluster_url_non_default.ini";
public static File createEmptyConfig() {
- return createIniFile(EMPTY);
+ return copyResourceToTempFile(EMPTY);
}
public static File createSectionWithInternalPart() {
- return createIniFile(TWO_SECTION_WITH_INTERNAL_PART);
+ return copyResourceToTempFile(TWO_SECTION_WITH_INTERNAL_PART);
}
public static File createSectionWithoutInternalPart() {
- return createIniFile(TWO_SECTION_WITHOUT_INTERNAL_PART);
+ return copyResourceToTempFile(TWO_SECTION_WITHOUT_INTERNAL_PART);
}
public static File createIntegrationTests() {
- return createIniFile(INTEGRATION_TESTS);
+ return copyResourceToTempFile(INTEGRATION_TESTS);
+ }
+
+ public static File createClusterUrlNonDefault() {
+ return copyResourceToTempFile(CLUSTER_URL_NON_DEFAULT);
}
- private static File createIniFile(String iniResource) {
+ /**
+ * Helper method to copy file from the classpath to the temporary file which will be deleted on exit.
+ *
+ * @param resource The resource name
+ * @return A temporary file containing the resource's contents
+ */
+ public static File copyResourceToTempFile(String resource) {
try {
File tempFile = File.createTempFile("cli", null);
try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
FileChannel dest = fileOutputStream.getChannel();
- InputStream resourceAsStream = TestConfigManagerHelper.class.getClassLoader().getResourceAsStream(iniResource);
+ InputStream resourceAsStream = TestConfigManagerHelper.class.getClassLoader().getResourceAsStream(resource);
ReadableByteChannel src = Channels.newChannel(resourceAsStream);
dest.transferFrom(src, 0, Integer.MAX_VALUE);
tempFile.deleteOnExit();
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java b/modules/cli/src/test/java/org/apache/ignite/cli/config/TestStateConfigHelper.java
similarity index 56%
copy from modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
copy to modules/cli/src/test/java/org/apache/ignite/cli/config/TestStateConfigHelper.java
index 31d47a5fb..62ce9cd50 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/config/TestStateConfigHelper.java
@@ -17,23 +17,24 @@
package org.apache.ignite.cli.config;
-import java.util.Map;
+import org.apache.ignite.cli.commands.cliconfig.TestConfigManagerHelper;
/**
- * Ignite CLI Profile.
+ * Test factory for application state config.
*/
-public interface Profile {
- String getName();
+public class TestStateConfigHelper {
+ public static final String EMPTY = "empty.ini";
+ public static final String LAST_CONNECTED_DEFAULT = "last_connected_default.ini";
- Map<String, String> getAll();
+ public static Config createEmptyConfig() {
+ return createConfig(EMPTY);
+ }
- String getProperty(String key);
+ public static Config createLastConnectedDefault() {
+ return createConfig(LAST_CONNECTED_DEFAULT);
+ }
- String getProperty(String key, String defaultValue);
-
- void setProperty(String key, String value);
-
- void setProperties(Map<String, String> values);
-
- void setProperties(Profile copyFrom);
+ private static Config createConfig(String resource) {
+ return StateConfig.getStateConfig(TestConfigManagerHelper.copyResourceToTempFile(resource));
+ }
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java b/modules/cli/src/test/java/org/apache/ignite/cli/config/TestStateConfigProvider.java
similarity index 68%
copy from modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
copy to modules/cli/src/test/java/org/apache/ignite/cli/config/TestStateConfigProvider.java
index 31d47a5fb..7b74b8d95 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/config/Profile.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/config/TestStateConfigProvider.java
@@ -17,23 +17,20 @@
package org.apache.ignite.cli.config;
-import java.util.Map;
+import io.micronaut.context.annotation.Replaces;
+import jakarta.inject.Singleton;
/**
- * Ignite CLI Profile.
+ * Test implementation of {@link StateConfigProvider}.
*/
-public interface Profile {
- String getName();
+@Singleton
+@Replaces(StateConfigProvider.class)
+public class TestStateConfigProvider implements StateConfigProvider {
- Map<String, String> getAll();
+ public Config config = TestStateConfigHelper.createEmptyConfig();
- String getProperty(String key);
-
- String getProperty(String key, String defaultValue);
-
- void setProperty(String key, String value);
-
- void setProperties(Map<String, String> values);
-
- void setProperties(Profile copyFrom);
+ @Override
+ public Config get() {
+ return config;
+ }
}
diff --git a/modules/cli/src/test/resources/cluster_url_non_default.ini b/modules/cli/src/test/resources/cluster_url_non_default.ini
new file mode 100644
index 000000000..ebdf2299c
--- /dev/null
+++ b/modules/cli/src/test/resources/cluster_url_non_default.ini
@@ -0,0 +1,5 @@
+[ignitecli_internal]
+current_profile = default
+
+[default]
+ignite.cluster-endpoint-url = http://localhost:10301
diff --git a/modules/cli/src/test/resources/last_connected_default.ini b/modules/cli/src/test/resources/last_connected_default.ini
new file mode 100644
index 000000000..7c7493766
--- /dev/null
+++ b/modules/cli/src/test/resources/last_connected_default.ini
@@ -0,0 +1 @@
+ignite.last-connected-url = http://localhost:10300