You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ib...@apache.org on 2021/08/16 10:39:02 UTC
[ignite-3] branch main updated: IGNITE-15285 Properly splitting
ConfigurationManager instances (node and cluster) (#273)
This is an automated email from the ASF dual-hosted git repository.
ibessonov 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 b82c1cb IGNITE-15285 Properly splitting ConfigurationManager instances (node and cluster) (#273)
b82c1cb is described below
commit b82c1cb70ef8603568991bff01e528e6917e488d
Author: Kirill Tkalenko <tk...@yandex.ru>
AuthorDate: Mon Aug 16 13:38:58 2021 +0300
IGNITE-15285 Properly splitting ConfigurationManager instances (node and cluster) (#273)
---
.../internal/affinity/AffinityManagerTest.java | 12 +-
.../org/apache/ignite/cli/ConfigCommandTest.java | 7 +-
.../cli/builtins/config/ConfigurationClient.java | 17 +-
.../apache/ignite/cli/spec/ConfigCommandSpec.java | 31 ++-
.../apache/ignite/cli/IgniteCliInterfaceTest.java | 31 ++-
.../handler/ClientHandlerIntegrationTest.java | 11 +-
.../apache/ignite/client/AbstractClientTest.java | 11 +-
.../configuration/ConfigurationChangerTest.java | 90 ++++----
.../configuration/TestConfigurationChanger.java | 33 ++-
.../configuration/hocon/HoconConverterTest.java | 14 +-
.../notifications/ConfigurationListenerTest.java | 16 +-
.../internal/configuration/sample/UsageTest.java | 20 +-
.../configuration/tree/NamedListNodeTest.java | 10 +-
.../configuration/util/ConfigurationUtilTest.java | 98 +++++++-
.../org/apache/ignite/configuration/RootKey.java | 18 +-
.../configuration/ConfigurationChanger.java | 247 +++++++--------------
.../configuration/ConfigurationManager.java | 55 ++---
.../configuration/ConfigurationRegistry.java | 94 ++++----
.../configuration/DynamicConfiguration.java | 2 +-
.../internal/configuration/DynamicProperty.java | 2 +-
.../configuration/util/ConfigurationUtil.java | 17 ++
.../java/org/apache/ignite/rest/RestModule.java | 199 +++++++++++------
.../rest/presentation/hocon/HoconPresentation.java | 2 +-
.../ConfigurationPresentationTest.java | 2 +-
.../ITDistributedConfigurationStorageTest.java | 12 +-
.../apache/ignite/internal/app/IgnitionImpl.java | 60 ++---
.../storage/LocalConfigurationStorage.java | 2 +-
.../SchemaConfigurationConverterTest.java | 16 +-
.../internal/table/distributed/TableManager.java | 57 ++---
.../ignite/internal/table/TableManagerTest.java | 60 ++---
30 files changed, 701 insertions(+), 545 deletions(-)
diff --git a/modules/affinity/src/test/java/org/apache/ignite/internal/affinity/AffinityManagerTest.java b/modules/affinity/src/test/java/org/apache/ignite/internal/affinity/AffinityManagerTest.java
index 48c814d..152c900 100644
--- a/modules/affinity/src/test/java/org/apache/ignite/internal/affinity/AffinityManagerTest.java
+++ b/modules/affinity/src/test/java/org/apache/ignite/internal/affinity/AffinityManagerTest.java
@@ -21,10 +21,10 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.table.TablesConfiguration;
import org.apache.ignite.internal.affinity.event.AffinityEvent;
import org.apache.ignite.internal.affinity.event.AffinityEventParameters;
@@ -50,6 +50,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -80,8 +81,11 @@ public class AffinityManagerTest {
@BeforeEach
void setUp() {
try {
- cfrMgr = new ConfigurationManager(rootConfigurationKeys(), Arrays.asList(
- new TestConfigurationStorage(ConfigurationType.DISTRIBUTED)));
+ cfrMgr = new ConfigurationManager(
+ rootConfigurationKeys(),
+ Map.of(),
+ new TestConfigurationStorage(DISTRIBUTED)
+ );
cfrMgr.start();
@@ -117,7 +121,7 @@ public class AffinityManagerTest {
" }\n" +
" }\n" +
" }\n" +
- "}", ConfigurationType.DISTRIBUTED);
+ "}");
}
catch (Exception e) {
LOG.error("Failed to bootstrap the test configuration manager.", e);
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/ConfigCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/ConfigCommandTest.java
index 63d0fd0..5d8d470 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/ConfigCommandTest.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/ConfigCommandTest.java
@@ -85,6 +85,7 @@ public class ConfigCommandTest extends AbstractCliTest {
"set",
"--node-endpoint",
"localhost:" + restPort,
+ "--type", "node", //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
"node.metastorageNodes=[\"localhost1\"]"
);
@@ -103,7 +104,8 @@ public class ConfigCommandTest extends AbstractCliTest {
"config",
"get",
"--node-endpoint",
- "localhost:" + restPort
+ "localhost:" + restPort,
+ "--type", "node" //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
);
assertEquals(0, exitCode);
@@ -123,7 +125,8 @@ public class ConfigCommandTest extends AbstractCliTest {
"--node-endpoint",
"localhost:" + restPort,
"--selector",
- "network"
+ "network",
+ "--type", "node" //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
);
assertEquals(0, exitCode);
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/builtins/config/ConfigurationClient.java b/modules/cli/src/main/java/org/apache/ignite/cli/builtins/config/ConfigurationClient.java
index 4a87abe..019e481 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/builtins/config/ConfigurationClient.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/builtins/config/ConfigurationClient.java
@@ -69,21 +69,24 @@ public class ConfigurationClient {
* @param host String representation of server node host.
* @param port Host REST port.
* @param rawHoconPath HOCON dot-delimited path of requested configuration.
+ * @param type Configuration type: {@code node} or {@code cluster}.
* @return JSON string with node configuration.
*/
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
public String get(
String host,
int port,
- @Nullable String rawHoconPath) {
+ @Nullable String rawHoconPath,
+ String type
+ ) {
var req = HttpRequest
.newBuilder()
.header("Content-Type", "application/json");
if (rawHoconPath == null)
- req.uri(URI.create("http://" + host + ":" + port + GET_URL));
+ req.uri(URI.create("http://" + host + ":" + port + GET_URL + type + "/"));
else
- req.uri(URI.create("http://" + host + ":" + port + GET_URL +
- rawHoconPath));
+ req.uri(URI.create("http://" + host + ":" + port + GET_URL + type + "/" + rawHoconPath));
try {
HttpResponse<String> res =
@@ -109,13 +112,15 @@ public class ConfigurationClient {
* @param rawHoconData Valid HOCON represented as a string.
* @param out PrintWriter for printing user messages.
* @param cs ColorScheme to enrich user messages.
+ * @param type Configuration type: {@code node} or {@code cluster}.
*/
- public void set(String host, int port, String rawHoconData, PrintWriter out, ColorScheme cs) {
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
+ public void set(String host, int port, String rawHoconData, PrintWriter out, ColorScheme cs, String type) {
var req = HttpRequest
.newBuilder()
.PUT(HttpRequest.BodyPublishers.ofString(renderJsonFromHocon(rawHoconData)))
.header("Content-Type", "application/json")
- .uri(URI.create("http://" + host + ":" + port + SET_URL))
+ .uri(URI.create("http://" + host + ":" + port + SET_URL + type + "/"))
.build();
try {
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/spec/ConfigCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/spec/ConfigCommandSpec.java
index 2be0cf1..63d8a96 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/spec/ConfigCommandSpec.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/spec/ConfigCommandSpec.java
@@ -54,10 +54,20 @@ public class ConfigCommandSpec extends CategorySpec {
)
private String selector;
+ /** Configuration type: {@code node} or {@code cluster}. */
+ @CommandLine.Option(
+ names = "--type",
+ description = "Configuration type (\"node\" or \"cluster\")",
+ required = true
+ )
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
+ private String type;
+
/** {@inheritDoc} */
@Override public void run() {
spec.commandLine().getOut().println(
- configurationClient.get(cfgHostnameOptions.host(), cfgHostnameOptions.port(), selector));
+ configurationClient.get(cfgHostnameOptions.host(), cfgHostnameOptions.port(), selector, type)
+ );
}
}
@@ -81,10 +91,25 @@ public class ConfigCommandSpec extends CategorySpec {
@CommandLine.Mixin
private CfgHostnameOptions cfgHostnameOptions;
+ /** Configuration type: {@code node} or {@code cluster}. */
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
+ @CommandLine.Option(
+ names = "--type",
+ description = "Configuration type (\"node\" or \"cluster\")",
+ required = true
+ )
+ private String type;
+
/** {@inheritDoc} */
@Override public void run() {
- configurationClient.set(cfgHostnameOptions.host(), cfgHostnameOptions.port(), cfg,
- spec.commandLine().getOut(), spec.commandLine().getColorScheme());
+ configurationClient.set(
+ cfgHostnameOptions.host(),
+ cfgHostnameOptions.port(),
+ cfg,
+ spec.commandLine().getOut(),
+ spec.commandLine().getColorScheme(),
+ type
+ );
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/IgniteCliInterfaceTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/IgniteCliInterfaceTest.java
index d787009..7d416c0 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/IgniteCliInterfaceTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/IgniteCliInterfaceTest.java
@@ -484,19 +484,20 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
}
/** */
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("get --node-endpoint localhost:8081")
+ @DisplayName("get --node-endpoint localhost:8081 --type node")
void get() throws IOException, InterruptedException {
when(res.statusCode()).thenReturn(HttpURLConnection.HTTP_OK);
when(res.body()).thenReturn("{\"baseline\":{\"autoAdjust\":{\"enabled\":true}}}");
when(httpClient.<String>send(any(), any())).thenReturn(res);
var exitCode =
- cmd(ctx).execute("config get --node-endpoint localhost:8081".split(" "));
+ cmd(ctx).execute("config get --node-endpoint localhost:8081 --type node".split(" "));
Assertions.assertEquals(0, exitCode);
verify(httpClient).send(
- argThat(r -> "http://localhost:8081/management/v1/configuration/".equals(r.uri().toString()) &&
+ argThat(r -> "http://localhost:8081/management/v1/configuration/node/".equals(r.uri().toString()) &&
"application/json".equals(r.headers().firstValue("Content-Type").get())),
any());
assertEquals("{\n" +
@@ -509,8 +510,9 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
}
/** */
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("get --node-endpoint localhost:8081 --selector local.baseline")
+ @DisplayName("get --node-endpoint localhost:8081 --selector local.baseline --type node")
void getSubtree() throws IOException, InterruptedException {
when(res.statusCode()).thenReturn(HttpURLConnection.HTTP_OK);
when(res.body()).thenReturn("{\"autoAdjust\":{\"enabled\":true}}");
@@ -518,12 +520,12 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
var exitCode =
cmd(ctx).execute(("config get --node-endpoint localhost:8081 " +
- "--selector local.baseline").split(" "));
+ "--selector local.baseline --type node").split(" "));
Assertions.assertEquals(0, exitCode);
verify(httpClient).send(
argThat(r ->
- "http://localhost:8081/management/v1/configuration/local.baseline".equals(r.uri().toString()) &&
+ "http://localhost:8081/management/v1/configuration/node/local.baseline".equals(r.uri().toString()) &&
"application/json".equals(r.headers().firstValue("Content-Type").get())),
any());
assertEquals("{\n" +
@@ -534,8 +536,9 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
}
/** */
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("set --node-endpoint localhost:8081 local.baseline.autoAdjust.enabled=true")
+ @DisplayName("set --node-endpoint localhost:8081 local.baseline.autoAdjust.enabled=true --type node")
void setHocon() throws IOException, InterruptedException {
when(res.statusCode()).thenReturn(HttpURLConnection.HTTP_OK);
when(httpClient.<String>send(any(), any())).thenReturn(res);
@@ -545,12 +548,12 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
var cmd = cmd(ctx);
var exitCode =
cmd.execute(("config set --node-endpoint localhost:8081 " +
- "local.baseline.autoAdjust.enabled=true"
+ "local.baseline.autoAdjust.enabled=true --type node"
).split(" "));
Assertions.assertEquals(0, exitCode);
verify(httpClient).send(
- argThat(r -> "http://localhost:8081/management/v1/configuration/".equals(r.uri().toString()) &&
+ argThat(r -> "http://localhost:8081/management/v1/configuration/node/".equals(r.uri().toString()) &&
"PUT".equals(r.method()) &&
r.bodyPublisher().get().contentLength() == expSentContent.getBytes().length &&
"application/json".equals(r.headers().firstValue("Content-Type").get())),
@@ -561,8 +564,12 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
}
/** */
+ //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("set --node-endpoint localhost:8081 {\"local\":{\"baseline\":{\"autoAdjust\":{\"enabled\":true}}}}")
+ @DisplayName(
+ "set --node-endpoint localhost:8081 {\"local\":{\"baseline\":{\"autoAdjust\":{\"enabled\":true}}}} " +
+ "--type node"
+ )
void setJson() throws IOException, InterruptedException {
when(res.statusCode()).thenReturn(HttpURLConnection.HTTP_OK);
when(httpClient.<String>send(any(), any())).thenReturn(res);
@@ -572,12 +579,12 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
var cmd = cmd(ctx);
var exitCode =
cmd.execute(("config set --node-endpoint localhost:8081 " +
- "local.baseline.autoAdjust.enabled=true"
+ "local.baseline.autoAdjust.enabled=true --type node"
).split(" "));
Assertions.assertEquals(0, exitCode);
verify(httpClient).send(
- argThat(r -> "http://localhost:8081/management/v1/configuration/".equals(r.uri().toString()) &&
+ argThat(r -> "http://localhost:8081/management/v1/configuration/node/".equals(r.uri().toString()) &&
"PUT".equals(r.method()) &&
r.bodyPublisher().get().contentLength() == expSentContent.getBytes().length &&
"application/json".equals(r.headers().firstValue("Content-Type").get())),
diff --git a/modules/client-handler/src/test/java/org/apache/ignite/client/handler/ClientHandlerIntegrationTest.java b/modules/client-handler/src/test/java/org/apache/ignite/client/handler/ClientHandlerIntegrationTest.java
index 29733db..5294065 100644
--- a/modules/client-handler/src/test/java/org/apache/ignite/client/handler/ClientHandlerIntegrationTest.java
+++ b/modules/client-handler/src/test/java/org/apache/ignite/client/handler/ClientHandlerIntegrationTest.java
@@ -21,10 +21,10 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
-import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import io.netty.channel.ChannelFuture;
import org.apache.ignite.app.Ignite;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.clientconnector.ClientConnectorConfiguration;
import org.apache.ignite.internal.configuration.ConfigurationRegistry;
import org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
import org.msgpack.core.MessagePack;
import org.slf4j.helpers.NOPLogger;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -179,9 +180,9 @@ public class ClientHandlerIntegrationTest {
private ChannelFuture startServer() throws InterruptedException {
configurationRegistry = new ConfigurationRegistry(
- Collections.singletonList(ClientConnectorConfiguration.KEY),
- Collections.emptyMap(),
- Collections.singletonList(new TestConfigurationStorage(ConfigurationType.LOCAL))
+ List.of(ClientConnectorConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(LOCAL)
);
configurationRegistry.start();
diff --git a/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTest.java b/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTest.java
index 416101c..64d7855 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTest.java
@@ -18,13 +18,13 @@
package org.apache.ignite.client;
import java.net.InetSocketAddress;
-import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import io.netty.channel.ChannelFuture;
import io.netty.util.ResourceLeakDetector;
import org.apache.ignite.app.Ignite;
import org.apache.ignite.client.fakes.FakeIgnite;
import org.apache.ignite.client.handler.ClientHandlerModule;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.clientconnector.ClientConnectorConfiguration;
import org.apache.ignite.internal.configuration.ConfigurationRegistry;
import org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.slf4j.helpers.NOPLogger;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -89,9 +90,9 @@ public abstract class AbstractClientTest {
public static ChannelFuture startServer(String host) throws InterruptedException {
configurationRegistry = new ConfigurationRegistry(
- Collections.singletonList(ClientConnectorConfiguration.KEY),
- Collections.emptyMap(),
- Collections.singletonList(new TestConfigurationStorage(ConfigurationType.LOCAL))
+ List.of(ClientConnectorConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(LOCAL)
);
configurationRegistry.start();
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java
index f7cc95d..b1e69fb 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java
@@ -22,6 +22,7 @@ import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import org.apache.ignite.configuration.ConfigurationChangeException;
@@ -29,7 +30,6 @@ import org.apache.ignite.configuration.RootKey;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.ConfigValue;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.annotation.NamedConfigValue;
import org.apache.ignite.configuration.annotation.Value;
import org.apache.ignite.configuration.validation.Immutable;
@@ -47,6 +47,7 @@ import org.junit.jupiter.api.Test;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.apache.ignite.internal.configuration.AConfiguration.KEY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -63,7 +64,7 @@ public class ConfigurationChangerTest {
}
/** */
- @ConfigurationRoot(rootName = "key", type = ConfigurationType.LOCAL)
+ @ConfigurationRoot(rootName = "key", type = LOCAL)
public static class AConfigurationSchema {
/** */
@ConfigValue
@@ -108,16 +109,15 @@ public class ConfigurationChangerTest {
*/
@Test
public void testSimpleConfigurationChange() throws Exception {
- var storage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ var storage = new TestConfigurationStorage(LOCAL);
- ConfigurationChanger changer = new TestConfigurationChanger(cgen);
- changer.addRootKey(KEY);
- changer.register(storage);
+ ConfigurationChanger changer = new TestConfigurationChanger(cgen, List.of(KEY), Map.of(), storage);
+ changer.start();
changer.change(source(KEY, (AChange parent) -> parent
.changeChild(change -> change.changeIntCfg(1).changeStrCfg("1"))
.changeElements(change -> change.create("a", element -> element.changeStrCfg("1")))
- ), null).get(1, SECONDS);
+ )).get(1, SECONDS);
AView newRoot = (AView)changer.getRootNode(KEY);
@@ -131,20 +131,18 @@ public class ConfigurationChangerTest {
*/
@Test
public void testModifiedFromAnotherStorage() throws Exception {
- var storage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ var storage = new TestConfigurationStorage(LOCAL);
- ConfigurationChanger changer1 = new TestConfigurationChanger(cgen);
- changer1.addRootKey(KEY);
- changer1.register(storage);
+ ConfigurationChanger changer1 = new TestConfigurationChanger(cgen, List.of(KEY), Map.of(), storage);
+ changer1.start();
- ConfigurationChanger changer2 = new TestConfigurationChanger(cgen);
- changer2.addRootKey(KEY);
- changer2.register(storage);
+ ConfigurationChanger changer2 = new TestConfigurationChanger(cgen, List.of(KEY), Map.of(), storage);
+ changer2.start();
changer1.change(source(KEY, (AChange parent) -> parent
.changeChild(change -> change.changeIntCfg(1).changeStrCfg("1"))
.changeElements(change -> change.create("a", element -> element.changeStrCfg("1")))
- ), null).get(1, SECONDS);
+ )).get(1, SECONDS);
changer2.change(source(KEY, (AChange parent) -> parent
.changeChild(change -> change.changeIntCfg(2).changeStrCfg("2"))
@@ -152,7 +150,7 @@ public class ConfigurationChangerTest {
.createOrUpdate("a", element -> element.changeStrCfg("2"))
.create("b", element -> element.changeStrCfg("2"))
)
- ), null).get(1, SECONDS);
+ )).get(1, SECONDS);
AView newRoot1 = (AView)changer1.getRootNode(KEY);
@@ -174,26 +172,31 @@ public class ConfigurationChangerTest {
*/
@Test
public void testModifiedFromAnotherStorageWithIncompatibleChanges() throws Exception {
- var storage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ var storage = new TestConfigurationStorage(LOCAL);
- ConfigurationChanger changer1 = new TestConfigurationChanger(cgen);
- changer1.addRootKey(KEY);
- changer1.register(storage);
+ ConfigurationChanger changer1 = new TestConfigurationChanger(cgen, List.of(KEY), Map.of(), storage);
+ changer1.start();
- ConfigurationChanger changer2 = new TestConfigurationChanger(cgen);
- changer2.addRootKey(KEY);
- changer2.register(storage);
+ Validator<MaybeInvalid, Object> validator = new Validator<>() {
+ /** {@inheritDoc} */
+ @Override public void validate(MaybeInvalid annotation, ValidationContext<Object> ctx) {
+ ctx.addIssue(new ValidationIssue("foo"));
+ }
+ };
+
+ ConfigurationChanger changer2 = new TestConfigurationChanger(
+ cgen,
+ List.of(KEY),
+ Map.of(MaybeInvalid.class, Set.of(validator)),
+ storage
+ );
+
+ changer2.start();
changer1.change(source(KEY, (AChange parent) -> parent
.changeChild(change -> change.changeIntCfg(1).changeStrCfg("1"))
.changeElements(change -> change.create("a", element -> element.changeStrCfg("1")))
- ), null).get(1, SECONDS);
-
- changer2.addValidator(MaybeInvalid.class, new Validator<MaybeInvalid, Object>() {
- @Override public void validate(MaybeInvalid annotation, ValidationContext<Object> ctx) {
- ctx.addIssue(new ValidationIssue("foo"));
- }
- });
+ )).get(1, SECONDS);
assertThrows(ExecutionException.class, () -> changer2.change(source(KEY, (AChange parent) -> parent
.changeChild(change -> change.changeIntCfg(2).changeStrCfg("2"))
@@ -201,7 +204,7 @@ public class ConfigurationChangerTest {
.create("a", element -> element.changeStrCfg("2"))
.create("b", element -> element.changeStrCfg("2"))
)
- ), null).get(1, SECONDS));
+ )).get(1, SECONDS));
AView newRoot = (AView)changer2.getRootNode(KEY);
@@ -215,24 +218,23 @@ public class ConfigurationChangerTest {
*/
@Test
public void testFailedToWrite() {
- var storage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ var storage = new TestConfigurationStorage(LOCAL);
- ConfigurationChanger changer = new TestConfigurationChanger(cgen);
- changer.addRootKey(KEY);
+ ConfigurationChanger changer = new TestConfigurationChanger(cgen, List.of(KEY), Map.of(), storage);
storage.fail(true);
- assertThrows(ConfigurationChangeException.class, () -> changer.register(storage));
+ assertThrows(ConfigurationChangeException.class, changer::start);
storage.fail(false);
- changer.register(storage);
+ changer.start();
storage.fail(true);
assertThrows(ExecutionException.class, () -> changer.change(source(KEY, (AChange parent) -> parent
.changeChild(child -> child.changeIntCfg(1))
- ), null).get(1, SECONDS));
+ )).get(1, SECONDS));
storage.fail(false);
@@ -246,7 +248,7 @@ public class ConfigurationChangerTest {
}
/** */
- @ConfigurationRoot(rootName = "def", type = ConfigurationType.LOCAL)
+ @ConfigurationRoot(rootName = "def", type = LOCAL)
public static class DefaultsConfigurationSchema {
/** */
@ConfigValue
@@ -275,15 +277,13 @@ public class ConfigurationChangerTest {
@Test
public void defaultsOnInit() throws Exception {
- var changer = new TestConfigurationChanger(cgen);
-
- changer.addRootKey(DefaultsConfiguration.KEY);
+ var storage = new TestConfigurationStorage(LOCAL);
- var storage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ var changer = new TestConfigurationChanger(cgen, List.of(DefaultsConfiguration.KEY), Map.of(), storage);
- changer.register(storage);
+ changer.start();
- changer.initialize(storage.type());
+ changer.initializeDefaults();
DefaultsView root = (DefaultsView)changer.getRootNode(DefaultsConfiguration.KEY);
@@ -295,7 +295,7 @@ public class ConfigurationChangerTest {
.changeChildsList(childs ->
childs.create("name", child -> {})
)
- ), null).get(1, SECONDS);
+ )).get(1, SECONDS);
root = (DefaultsView)changer.getRootNode(DefaultsConfiguration.KEY);
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/TestConfigurationChanger.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/TestConfigurationChanger.java
index 23f27d3..0d80082 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/TestConfigurationChanger.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/TestConfigurationChanger.java
@@ -17,8 +17,14 @@
package org.apache.ignite.internal.configuration;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
import org.apache.ignite.configuration.RootKey;
+import org.apache.ignite.configuration.validation.Validator;
import org.apache.ignite.internal.configuration.asm.ConfigurationAsmGenerator;
+import org.apache.ignite.internal.configuration.storage.ConfigurationStorage;
import org.apache.ignite.internal.configuration.tree.InnerNode;
import static java.util.concurrent.CompletableFuture.completedFuture;
@@ -29,19 +35,30 @@ public class TestConfigurationChanger extends ConfigurationChanger {
private final ConfigurationAsmGenerator cgen;
/**
+ * Constructor.
+ *
* @param cgen Runtime implementations generator for node classes. Will be used to instantiate nodes objects.
+ * @param rootKeys Configuration root keys.
+ * @param validators Validators.
+ * @param storage Configuration storage.
+ * @throws IllegalArgumentException If the configuration type of the root keys is not equal to the storage type.
*/
- public TestConfigurationChanger(ConfigurationAsmGenerator cgen) {
- super((oldRoot, newRoot, revision) -> completedFuture(null));
+ public TestConfigurationChanger(
+ ConfigurationAsmGenerator cgen,
+ Collection<RootKey<?, ?>> rootKeys,
+ Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators,
+ ConfigurationStorage storage
+ ) {
+ super(
+ (oldRoot, newRoot, revision) -> completedFuture(null),
+ rootKeys,
+ validators,
+ storage
+ );
this.cgen = cgen;
- }
-
- /** {@inheritDoc} */
- @Override public void addRootKey(RootKey<?, ?> rootKey) {
- super.addRootKey(rootKey);
- cgen.compileRootSchema(rootKey.schemaClass());
+ rootKeys.forEach(key -> cgen.compileRootSchema(key.schemaClass()));
}
/** {@inheritDoc} */
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/hocon/HoconConverterTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/hocon/HoconConverterTest.java
index 5b151d5..85174e8 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/hocon/HoconConverterTest.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/hocon/HoconConverterTest.java
@@ -18,8 +18,8 @@
package org.apache.ignite.internal.configuration.hocon;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -28,7 +28,6 @@ import com.typesafe.config.ConfigRenderOptions;
import com.typesafe.config.ConfigValue;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.annotation.NamedConfigValue;
import org.apache.ignite.configuration.annotation.Value;
import org.apache.ignite.internal.configuration.ConfigurationRegistry;
@@ -40,6 +39,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.apache.ignite.internal.configuration.hocon.HoconConverter.hoconSource;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
@@ -53,7 +53,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
*/
public class HoconConverterTest {
/** */
- @ConfigurationRoot(rootName = "root", type = ConfigurationType.LOCAL)
+ @ConfigurationRoot(rootName = "root", type = LOCAL)
public static class HoconRootConfigurationSchema {
/** */
@NamedConfigValue(syntheticKeyName = "a")
@@ -158,9 +158,9 @@ public class HoconConverterTest {
@BeforeAll
public static void beforeAll() {
registry = new ConfigurationRegistry(
- Collections.singletonList(HoconRootConfiguration.KEY),
- Collections.emptyMap(),
- Collections.singletonList(new TestConfigurationStorage(ConfigurationType.LOCAL))
+ List.of(HoconRootConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(LOCAL)
);
registry.start();
@@ -553,7 +553,7 @@ public class HoconConverterTest {
*/
private void change(String hocon) throws Throwable {
try {
- registry.change(hoconSource(ConfigFactory.parseString(hocon).root()), null).get(1, SECONDS);
+ registry.change(hoconSource(ConfigFactory.parseString(hocon).root())).get(1, SECONDS);
}
catch (ExecutionException e) {
throw e.getCause();
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java
index bb631c0..77753dd 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java
@@ -18,15 +18,14 @@
package org.apache.ignite.internal.configuration.notifications;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.ConfigValue;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.annotation.NamedConfigValue;
import org.apache.ignite.configuration.annotation.Value;
import org.apache.ignite.configuration.notifications.ConfigurationNamedListListener;
@@ -39,6 +38,7 @@ import org.junit.jupiter.api.Test;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -48,7 +48,7 @@ import static org.junit.jupiter.api.Assertions.fail;
/** */
public class ConfigurationListenerTest {
/** */
- @ConfigurationRoot(rootName = "parent", type = ConfigurationType.LOCAL)
+ @ConfigurationRoot(rootName = "parent", type = LOCAL)
public static class ParentConfigurationSchema {
/** */
@ConfigValue
@@ -76,17 +76,13 @@ public class ConfigurationListenerTest {
/** */
@BeforeEach
public void before() {
- var testConfigurationStorage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ var testConfigurationStorage = new TestConfigurationStorage(LOCAL);
- registry = new ConfigurationRegistry(
- Collections.singletonList(ParentConfiguration.KEY),
- Collections.emptyMap(),
- Collections.singletonList(testConfigurationStorage)
- );
+ registry = new ConfigurationRegistry(List.of(ParentConfiguration.KEY), Map.of(), testConfigurationStorage);
registry.start();
- registry.startStorageConfigurations(testConfigurationStorage.type());
+ registry.initializeDefaults();
configuration = registry.getConfiguration(ParentConfiguration.KEY);
}
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java
index df521e7..72a8f0a 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java
@@ -17,15 +17,15 @@
package org.apache.ignite.internal.configuration.sample;
-import java.util.Arrays;
-import java.util.Collections;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
+import java.util.List;
+import java.util.Map;
import org.apache.ignite.internal.configuration.ConfigurationRegistry;
import org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -50,14 +50,14 @@ public class UsageTest {
@Test
public void test() throws Exception {
registry = new ConfigurationRegistry(
- Collections.singletonList(LocalConfiguration.KEY),
- Collections.emptyMap(),
- Collections.singletonList(new TestConfigurationStorage(ConfigurationType.LOCAL))
+ List.of(LocalConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(LOCAL)
);
registry.start();
- registry.startStorageConfigurations(ConfigurationType.LOCAL);
+ registry.initializeDefaults();
LocalConfiguration root = registry.getConfiguration(LocalConfiguration.KEY);
@@ -110,9 +110,9 @@ public class UsageTest {
long autoAdjustTimeout = 30_000L;
registry = new ConfigurationRegistry(
- Arrays.asList(NetworkConfiguration.KEY, LocalConfiguration.KEY),
- Collections.emptyMap(),
- Collections.singletonList(new TestConfigurationStorage(ConfigurationType.LOCAL))
+ List.of(NetworkConfiguration.KEY, LocalConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(LOCAL)
);
registry.start();
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/tree/NamedListNodeTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/tree/NamedListNodeTest.java
index 6f87b3a..e1b1491 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/tree/NamedListNodeTest.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/tree/NamedListNodeTest.java
@@ -18,10 +18,10 @@
package org.apache.ignite.internal.configuration.tree;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.annotation.NamedConfigValue;
import org.apache.ignite.configuration.annotation.Value;
import org.apache.ignite.internal.configuration.TestConfigurationChanger;
@@ -35,6 +35,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static java.lang.String.format;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.aMapWithSize;
import static org.hamcrest.Matchers.anEmptyMap;
@@ -87,11 +88,10 @@ public class NamedListNodeTest {
/** */
@BeforeEach
public void before() {
- storage = new TestConfigurationStorage(ConfigurationType.LOCAL);
+ storage = new TestConfigurationStorage(LOCAL);
- changer = new TestConfigurationChanger(cgen);
- changer.addRootKey(AConfiguration.KEY);
- changer.register(storage);
+ changer = new TestConfigurationChanger(cgen, List.of(AConfiguration.KEY), Map.of(), storage);
+ changer.start();
}
/** */
diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
index 9bf04cc..fa72dff 100644
--- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
+++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
@@ -21,14 +21,15 @@ import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import org.apache.ignite.configuration.RootKey;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.ConfigValue;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.annotation.NamedConfigValue;
import org.apache.ignite.configuration.annotation.Value;
import org.apache.ignite.internal.configuration.SuperRoot;
import org.apache.ignite.internal.configuration.asm.ConfigurationAsmGenerator;
+import org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
import org.apache.ignite.internal.configuration.tree.ConfigurationSource;
import org.apache.ignite.internal.configuration.tree.InnerNode;
import org.apache.ignite.internal.configuration.tree.TraversableTreeNode;
@@ -38,9 +39,12 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static java.util.Collections.singletonMap;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.apache.ignite.internal.configuration.tree.NamedListNode.NAME;
import static org.apache.ignite.internal.configuration.tree.NamedListNode.ORDER_IDX;
import static org.apache.ignite.internal.configuration.util.ConfigurationFlattener.createFlattenedUpdatesMap;
+import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.checkConfigurationType;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.aMapWithSize;
import static org.hamcrest.Matchers.allOf;
@@ -112,7 +116,7 @@ public class ConfigurationUtilTest {
}
/** */
- @ConfigurationRoot(rootName = "root", type = ConfigurationType.LOCAL)
+ @ConfigurationRoot(rootName = "root", type = LOCAL)
public static class ParentConfigurationSchema {
/** */
@NamedConfigValue
@@ -341,6 +345,56 @@ public class ConfigurationUtilTest {
);
}
+ /** */
+ @Test
+ void testCheckConfigurationTypeMixedTypes() {
+ List<RootKey<?, ?>> rootKeys = List.of(LocalFirstConfiguration.KEY, DistributedFirstConfiguration.KEY);
+
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> checkConfigurationType(rootKeys, new TestConfigurationStorage(LOCAL))
+ );
+
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> checkConfigurationType(rootKeys, new TestConfigurationStorage(DISTRIBUTED))
+ );
+ }
+
+ /** */
+ @Test
+ void testCheckConfigurationTypeOppositeTypes() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> checkConfigurationType(
+ List.of(DistributedFirstConfiguration.KEY, DistributedSecondConfiguration.KEY),
+ new TestConfigurationStorage(LOCAL)
+ )
+ );
+
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> checkConfigurationType(
+ List.of(LocalFirstConfiguration.KEY, LocalSecondConfiguration.KEY),
+ new TestConfigurationStorage(DISTRIBUTED)
+ )
+ );
+ }
+
+ /** */
+ @Test
+ void testCheckConfigurationTypeNoError() {
+ checkConfigurationType(
+ List.of(LocalFirstConfiguration.KEY, LocalSecondConfiguration.KEY),
+ new TestConfigurationStorage(LOCAL)
+ );
+
+ checkConfigurationType(
+ List.of(DistributedFirstConfiguration.KEY, DistributedSecondConfiguration.KEY),
+ new TestConfigurationStorage(DISTRIBUTED)
+ );
+ }
+
/**
* Patches super root and returns flat representation of the changes. Passed {@code superRoot} object will contain
* patched tree when method execution is completed.
@@ -362,4 +416,44 @@ public class ConfigurationUtilTest {
// Create flat diff between two super trees.
return createFlattenedUpdatesMap(originalSuperRoot, superRoot);
}
+
+ /**
+ * First local configuration.
+ */
+ @ConfigurationRoot(rootName = "localFirst", type = LOCAL)
+ public static class LocalFirstConfigurationSchema {
+ /** String field. */
+ @Value(hasDefault = true)
+ public String str = "str";
+ }
+
+ /**
+ * Second local configuration.
+ */
+ @ConfigurationRoot(rootName = "localSecond", type = LOCAL)
+ public static class LocalSecondConfigurationSchema {
+ /** String field. */
+ @Value(hasDefault = true)
+ public String str = "str";
+ }
+
+ /**
+ * First distributed configuration.
+ */
+ @ConfigurationRoot(rootName = "distributedFirst", type = DISTRIBUTED)
+ public static class DistributedFirstConfigurationSchema {
+ /** String field. */
+ @Value(hasDefault = true)
+ public String str = "str";
+ }
+
+ /**
+ * Second distributed configuration.
+ */
+ @ConfigurationRoot(rootName = "distributedSecond", type = DISTRIBUTED)
+ public static class DistributedSecondConfigurationSchema {
+ /** String field. */
+ @Value(hasDefault = true)
+ public String str = "str";
+ }
}
diff --git a/modules/configuration-api/src/main/java/org/apache/ignite/configuration/RootKey.java b/modules/configuration-api/src/main/java/org/apache/ignite/configuration/RootKey.java
index 93ec620..3ff15be 100644
--- a/modules/configuration-api/src/main/java/org/apache/ignite/configuration/RootKey.java
+++ b/modules/configuration-api/src/main/java/org/apache/ignite/configuration/RootKey.java
@@ -19,6 +19,7 @@ package org.apache.ignite.configuration;
import org.apache.ignite.configuration.annotation.ConfigurationRoot;
import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.internal.tostring.S;
/**
* Configuration root selector.
@@ -27,19 +28,13 @@ import org.apache.ignite.configuration.annotation.ConfigurationType;
* @param <VIEW> Type of the immutable snapshot view associated with the tree.
*/
public class RootKey<T extends ConfigurationTree<VIEW, ?>, VIEW> {
- /**
- * Name of the configuration root.
- */
+ /** Name of the configuration root. */
private final String rootName;
- /**
- * Configuration type of the root.
- */
+ /** Configuration type of the root. */
private final ConfigurationType storageType;
- /**
- * Schema class for the root.
- */
+ /** Schema class for the root. */
private final Class<?> schemaClass;
/**
@@ -84,4 +79,9 @@ public class RootKey<T extends ConfigurationTree<VIEW, ?>, VIEW> {
public Class<?> schemaClass() {
return schemaClass;
}
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(RootKey.class, this);
+ }
}
diff --git a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationChanger.java b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationChanger.java
index 153da64..b64f291 100644
--- a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationChanger.java
+++ b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationChanger.java
@@ -18,22 +18,17 @@ package org.apache.ignite.internal.configuration;
import java.io.Serializable;
import java.lang.annotation.Annotation;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Set;
-import java.util.TreeMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Function;
-import java.util.stream.Collectors;
import org.apache.ignite.configuration.ConfigurationChangeException;
import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.validation.ConfigurationValidationException;
import org.apache.ignite.configuration.validation.ValidationIssue;
import org.apache.ignite.configuration.validation.Validator;
@@ -47,12 +42,13 @@ import org.apache.ignite.internal.configuration.validation.MemberKey;
import org.apache.ignite.internal.configuration.validation.ValidationUtil;
import org.apache.ignite.lang.NodeStoppingException;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import static java.util.concurrent.CompletableFuture.completedFuture;
-import static java.util.stream.Collectors.toList;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
import static org.apache.ignite.internal.configuration.util.ConfigurationFlattener.createFlattenedUpdatesMap;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.addDefaults;
+import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.checkConfigurationType;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.dropNulls;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.fillFromPrefixMap;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.toPrefixMap;
@@ -61,26 +57,36 @@ import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.to
* Class that handles configuration changes, by validating them, passing to storage and listening to storage updates.
*/
public abstract class ConfigurationChanger {
- /** */
+ /** Thread pool. */
private final ForkJoinPool pool = new ForkJoinPool(2);
- /** */
- private final Map<String, RootKey<?, ?>> rootKeys = new TreeMap<>();
+ /** Lazy annotations cache for configuration schema fields. */
+ private final Map<MemberKey, Annotation[]> cachedAnnotations = new ConcurrentHashMap<>();
+
+ /** Closure to execute when an update from the storage is received. */
+ private final Notificator notificator;
+
+ /** Root keys. Mapping: {@link RootKey#key()} -> identity (itself). */
+ private final Map<String, RootKey<?, ?>> rootKeys;
- /** Map that has all the trees in accordance to their storages. */
- private final Map<ConfigurationType, StorageRoots> storagesRootsMap = new ConcurrentHashMap<>();
+ /** Validators. */
+ private final Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators;
- /** Annotation classes mapped to validator objects. */
- private Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators = new HashMap<>();
+ /** Configuration storage. */
+ private final ConfigurationStorage storage;
+
+ /** Storage trees. */
+ private volatile StorageRoots storageRoots;
/**
- * Closure interface to be used by the configuration changer. An instance of this closure is passed into the constructor and
- * invoked every time when there's an update from any of the storages.
+ * Closure interface to be used by the configuration changer. An instance of this closure is passed into
+ * the constructor and invoked every time when there's an update from any of the storages.
*/
@FunctionalInterface
public interface Notificator {
/**
* Invoked every time when the configuration is updated.
+ *
* @param oldRoot Old roots values. All these roots always belong to a single storage.
* @param newRoot New values for the same roots as in {@code oldRoot}.
* @param storageRevision Revision of the storage.
@@ -90,9 +96,6 @@ public abstract class ConfigurationChanger {
@NotNull CompletableFuture<Void> notify(SuperRoot oldRoot, SuperRoot newRoot, long storageRevision);
}
- /** Closure to execute when an update from the storage is received. */
- private final Notificator notificator;
-
/**
* Immutable data container to store version and all roots associated with the specific storage.
*/
@@ -106,61 +109,45 @@ public abstract class ConfigurationChanger {
/** Future that signifies update of current configuration. */
private final CompletableFuture<Void> changeFuture = new CompletableFuture<>();
- /** */
+ /**
+ * Constructor.
+ *
+ * @param roots Forest.
+ * @param version Version associated with the currently known storage state.
+ */
private StorageRoots(SuperRoot roots, long version) {
this.roots = roots;
this.version = version;
}
}
- /** Lazy annotations cache for configuration schema fields. */
- private final Map<MemberKey, Annotation[]> cachedAnnotations = new ConcurrentHashMap<>();
-
- /** Storage instances by their classes. Comes in handy when all you have is {@link RootKey}. */
- private final Map<ConfigurationType, ConfigurationStorage> storageInstances = new HashMap<>();
-
/**
+ * Constructor.
+ *
* @param notificator Closure to execute when update from the storage is received.
+ * @param rootKeys Configuration root keys.
+ * @param validators Validators.
+ * @param storage Configuration storage.
+ * @throws IllegalArgumentException If the configuration type of the root keys is not equal to the storage type.
*/
- public ConfigurationChanger(Notificator notificator) {
- this.notificator = notificator;
- }
-
- /**
- * Adds a single validator instance.
- * @param annotationType Annotation type for validated fields.
- * @param validator Validator instance for this annotation.
- * @param <A> Annotation type.
- */
- public <A extends Annotation> void addValidator(Class<A> annotationType, Validator<A, ?> validator) {
- validators
- .computeIfAbsent(annotationType, a -> new HashSet<>())
- .add(validator);
- }
-
- /**
- * Adds multiple validators instances.
- * @param annotationType Annotation type for validated fields.
- * @param validators Set of validator instancec for this annotation.
- */
- public void addValidators(Class<? extends Annotation> annotationType, Set<Validator<? extends Annotation, ?>> validators) {
- this.validators
- .computeIfAbsent(annotationType, a -> new HashSet<>())
- .addAll(validators);
- }
+ public ConfigurationChanger(
+ Notificator notificator,
+ Collection<RootKey<?, ?>> rootKeys,
+ Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators,
+ ConfigurationStorage storage
+ ) {
+ checkConfigurationType(rootKeys, storage);
- /**
- * Registers an additional root key.
- * @param rootKey Root key instance.
- */
- public void addRootKey(RootKey<?, ?> rootKey) {
- assert !storageInstances.containsKey(rootKey.type());
+ this.notificator = notificator;
+ this.validators = validators;
+ this.storage = storage;
- rootKeys.put(rootKey.key(), rootKey);
+ this.rootKeys = rootKeys.stream().collect(toMap(RootKey::key, identity()));
}
/**
- * Created new {@code Node} object that corresponds to passed root keys root configuration node.
+ * Creates new {@code Node} object that corresponds to passed root keys root configuration node.
+ *
* @param rootKey Root key.
* @return New {@link InnerNode} instance that represents root.
*/
@@ -168,9 +155,10 @@ public abstract class ConfigurationChanger {
/**
* Utility method to create {@link SuperRoot} parameter value.
+ *
* @return Function that creates root node by root name or returns {@code null} if root name is not found.
*/
- @NotNull private Function<String, InnerNode> rootCreator() {
+ private Function<String, InnerNode> rootCreator() {
return key -> {
RootKey<?, ?> rootKey = rootKeys.get(key);
@@ -179,21 +167,14 @@ public abstract class ConfigurationChanger {
}
/**
- * Registers a storage.
- * @param configurationStorage Configuration storage instance.
+ * Start component.
*/
// ConfigurationChangeException, really?
- public void register(ConfigurationStorage configurationStorage) throws ConfigurationChangeException {
- storageInstances.put(configurationStorage.type(), configurationStorage);
-
- Set<RootKey<?, ?>> storageRootKeys = rootKeys.values().stream().filter(
- rootKey -> configurationStorage.type() == rootKey.type()
- ).collect(Collectors.toSet());
-
+ public void start() throws ConfigurationChangeException {
Data data;
try {
- data = configurationStorage.readAll();
+ data = storage.readAll();
}
catch (StorageException e) {
throw new ConfigurationChangeException("Failed to initialize configuration: " + e.getMessage(), e);
@@ -203,7 +184,7 @@ public abstract class ConfigurationChanger {
Map<String, ?> dataValuesPrefixMap = toPrefixMap(data.values());
- for (RootKey<?, ?> rootKey : storageRootKeys) {
+ for (RootKey<?, ?> rootKey : rootKeys.values()) {
Map<String, ?> rootPrefixMap = (Map<String, ?>)dataValuesPrefixMap.get(rootKey.key());
InnerNode rootNode = createRootNode(rootKey);
@@ -214,36 +195,27 @@ public abstract class ConfigurationChanger {
superRoot.addRoot(rootKey, rootNode);
}
- StorageRoots storageRoots = new StorageRoots(superRoot, data.changeId());
+ storageRoots = new StorageRoots(superRoot, data.changeId());
- storagesRootsMap.put(configurationStorage.type(), storageRoots);
-
- configurationStorage.registerConfigurationListener(changedEntries -> updateFromListener(
- configurationStorage.type(),
- changedEntries
- ));
+ storage.registerConfigurationListener(this::updateFromListener);
}
/**
* Initializes the configuration storage - reads data and sets default values for missing configuration properties.
- * @param storageType Storage type.
+ *
* @throws ConfigurationValidationException If configuration validation failed.
- * @throws ConfigurationChangeException If configuration framework failed to add default values and save them to
- * storage.
+ * @throws ConfigurationChangeException If configuration framework failed to add default values and save them to storage.
*/
- public void initialize(ConfigurationType storageType) throws ConfigurationValidationException, ConfigurationChangeException {
- ConfigurationStorage configurationStorage = storageInstances.get(storageType);
-
- assert configurationStorage != null : storageType;
-
+ public void initializeDefaults() throws ConfigurationValidationException, ConfigurationChangeException {
try {
ConfigurationSource defaultsCfgSource = new ConfigurationSource() {
+ /** {@inheritDoc} */
@Override public void descend(ConstructableTreeNode node) {
addDefaults((InnerNode)node);
}
};
- changeInternally(defaultsCfgSource, configurationStorage).get();
+ changeInternally(defaultsCfgSource).get();
}
catch (ExecutionException e) {
Throwable cause = e.getCause();
@@ -255,75 +227,34 @@ public abstract class ConfigurationChanger {
throw (ConfigurationChangeException)cause;
throw new ConfigurationChangeException(
- "Failed to write defalut configuration values into the storage " + configurationStorage.getClass(), e
+ "Failed to write default configuration values into the storage " + storage.getClass(), e
);
}
catch (InterruptedException e) {
throw new ConfigurationChangeException(
- "Failed to initialize configuration storage " + configurationStorage.getClass(), e
+ "Failed to initialize configuration storage " + storage.getClass(), e
);
}
}
/**
* Changes the configuration.
+ *
* @param source Configuration source to create patch from.
- * @param storage Expected storage for the changes. If null, a derived storage will be used
- * unconditionaly.
* @return Future that is completed on change completion.
*/
- public CompletableFuture<Void> change(
- ConfigurationSource source,
- @Nullable ConfigurationStorage storage
- ) {
- Set<ConfigurationType> storagesTypes = new HashSet<>();
-
- ConstructableTreeNode collector = new ConstructableTreeNode() {
- @Override public void construct(String key, ConfigurationSource src) throws NoSuchElementException {
- RootKey<?, ?> rootKey = rootKeys.get(key);
-
- if (rootKey == null)
- throw new NoSuchElementException(key);
-
- storagesTypes.add(rootKey.type());
- }
-
- @Override public ConstructableTreeNode copy() {
- throw new UnsupportedOperationException("copy");
- }
- };
-
- source.reset();
-
- source.descend(collector);
-
- assert !storagesTypes.isEmpty();
-
- if (storagesTypes.size() != 1) {
- return CompletableFuture.failedFuture(
- new ConfigurationChangeException(
- "Cannot handle change request with configuration patches belonging to different storages."
- )
- );
- }
-
- ConfigurationStorage actualStorage = storageInstances.get(storagesTypes.iterator().next());
-
- if (storage != null && storage != actualStorage) {
- return CompletableFuture.failedFuture(
- new ConfigurationChangeException("Mismatched storage passed.")
- );
- }
-
- return changeInternally(source, actualStorage);
+ public CompletableFuture<Void> change(ConfigurationSource source) {
+ return changeInternally(source);
}
/** Stop component. */
public void stop() {
pool.shutdownNow();
- for (StorageRoots storageRoots : storagesRootsMap.values())
- storageRoots.changeFuture.completeExceptionally(new NodeStoppingException());
+ StorageRoots roots = storageRoots;
+
+ if (roots != null)
+ roots.changeFuture.completeExceptionally(new NodeStoppingException());
}
/**
@@ -333,32 +264,30 @@ public abstract class ConfigurationChanger {
* @return Root node.
*/
public InnerNode getRootNode(RootKey<?, ?> rootKey) {
- return storagesRootsMap.get(rootKey.type()).roots.getRoot(rootKey);
+ return storageRoots.roots.getRoot(rootKey);
}
/**
- * @return Super root chat contains roots belonging to all storages.
+ * Get storage super root.
+ *
+ * @return Super root storage.
*/
- public SuperRoot mergedSuperRoot() {
- return new SuperRoot(rootCreator(), storagesRootsMap.values().stream().map(roots -> roots.roots).collect(toList()));
+ public SuperRoot superRoot() {
+ return storageRoots.roots;
}
/**
* Internal configuration change method that completes provided future.
*
* @param src Configuration source.
- * @param storage Storage instance.
* @return fut Future that will be completed after changes are written to the storage.
*/
- private CompletableFuture<Void> changeInternally(
- ConfigurationSource src,
- ConfigurationStorage storage
- ) {
- StorageRoots storageRoots = storagesRootsMap.get(storage.type());
+ private CompletableFuture<Void> changeInternally(ConfigurationSource src) {
+ StorageRoots localRoots = storageRoots;
return CompletableFuture
.supplyAsync(() -> {
- SuperRoot curRoots = storageRoots.roots;
+ SuperRoot curRoots = localRoots.roots;
SuperRoot changes = curRoots.copy();
@@ -393,12 +322,12 @@ public abstract class ConfigurationChanger {
if (allChanges == null)
return completedFuture(null);
- return storage.write(allChanges, storageRoots.version)
+ return storage.write(allChanges, localRoots.version)
.thenCompose(casResult -> {
if (casResult)
- return storageRoots.changeFuture;
+ return localRoots.changeFuture;
else
- return storageRoots.changeFuture.thenCompose(v -> changeInternally(src, storage));
+ return localRoots.changeFuture.thenCompose(v -> changeInternally(src));
})
.exceptionally(throwable -> {
throw new ConfigurationChangeException("Failed to change configuration", throwable);
@@ -409,15 +338,11 @@ public abstract class ConfigurationChanger {
/**
* Updates configuration from storage listener.
*
- * @param storageType Type of the storage that propagated these changes.
* @param changedEntries Changed data.
* @return Future that signifies update completion.
*/
- private CompletableFuture<Void> updateFromListener(
- ConfigurationType storageType,
- Data changedEntries
- ) {
- StorageRoots oldStorageRoots = this.storagesRootsMap.get(storageType);
+ private CompletableFuture<Void> updateFromListener(Data changedEntries) {
+ StorageRoots oldStorageRoots = storageRoots;
Map<String, ?> dataValuesPrefixMap = toPrefixMap(changedEntries.values());
@@ -430,9 +355,7 @@ public abstract class ConfigurationChanger {
long newChangeId = changedEntries.changeId();
- StorageRoots newStorageRoots = new StorageRoots(newSuperRoot, newChangeId);
-
- storagesRootsMap.put(storageType, newStorageRoots);
+ storageRoots = new StorageRoots(newSuperRoot, newChangeId);
return notificator.notify(oldSuperRoot, newSuperRoot, newChangeId)
.whenComplete((v, t) -> {
diff --git a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationManager.java b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationManager.java
index f38da2c..c1c6056 100644
--- a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationManager.java
+++ b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationManager.java
@@ -19,97 +19,74 @@ package org.apache.ignite.internal.configuration;
import java.lang.annotation.Annotation;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigObject;
import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.validation.Validator;
import org.apache.ignite.internal.configuration.hocon.HoconConverter;
import org.apache.ignite.internal.configuration.storage.ConfigurationStorage;
import org.apache.ignite.internal.manager.IgniteComponent;
+import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.checkConfigurationType;
+
/**
* Configuration manager is responsible for handling configuration lifecycle and provides configuration API.
*/
public class ConfigurationManager implements IgniteComponent {
/** Configuration registry. */
- private final ConfigurationRegistry confRegistry;
-
- /** Type mapped to configuration storage. */
- private final Map<ConfigurationType, ConfigurationStorage> configurationStorages;
+ private final ConfigurationRegistry registry;
/**
- * The constructor.
+ * Constructor.
*
* @param rootKeys Configuration root keys.
* @param validators Validators.
- * @param configurationStorages Configuration storages.
+ * @param storage Configuration storage.
+ * @throws IllegalArgumentException If the configuration type of the root keys is not equal to the storage type.
*/
public ConfigurationManager(
Collection<RootKey<?, ?>> rootKeys,
Map<Class<? extends Annotation>, Set<Validator<? extends Annotation, ?>>> validators,
- Collection<ConfigurationStorage> configurationStorages
+ ConfigurationStorage storage
) {
- HashMap<ConfigurationType, ConfigurationStorage> storageByType = new HashMap<>();
-
- for (ConfigurationStorage storage : configurationStorages) {
- assert !storageByType.containsKey(storage.type()) : "Two or more storage have the same configuration type [type=" + storage.type() + ']';
-
- storageByType.put(storage.type(), storage);
- }
+ checkConfigurationType(rootKeys, storage);
- this.configurationStorages = Map.copyOf(storageByType);
-
- confRegistry = new ConfigurationRegistry(rootKeys, validators, configurationStorages);
+ registry = new ConfigurationRegistry(rootKeys, validators, storage);
}
/** {@inheritDoc} */
@Override public void start() {
- confRegistry.start();
+ registry.start();
}
/** {@inheritDoc} */
@Override public void stop() {
// TODO: IGNITE-15161 Implement component's stop.
- confRegistry.stop();
- }
-
- /**
- * Constructor.
- *
- * @param rootKeys Configuration root keys.
- * @param configurationStorages Configuration storages.
- */
- public ConfigurationManager(
- Collection<RootKey<?, ?>> rootKeys,
- Collection<ConfigurationStorage> configurationStorages
- ) {
- this(rootKeys, Collections.emptyMap(), configurationStorages);
+ registry.stop();
}
/**
* Bootstrap configuration manager with customer user cfg.
*
* @param hoconStr Customer configuration in hocon format.
- * @param type Configuration type.
* @throws InterruptedException If thread is interrupted during bootstrap.
* @throws ExecutionException If configuration update failed for some reason.
*/
- public void bootstrap(String hoconStr, ConfigurationType type) throws InterruptedException, ExecutionException {
+ public void bootstrap(String hoconStr) throws InterruptedException, ExecutionException {
ConfigObject hoconCfg = ConfigFactory.parseString(hoconStr).root();
- confRegistry.change(HoconConverter.hoconSource(hoconCfg), configurationStorages.get(type)).get();
+ registry.change(HoconConverter.hoconSource(hoconCfg)).get();
}
/**
+ * Get configuration registry.
+ *
* @return Configuration registry.
*/
public ConfigurationRegistry configurationRegistry() {
- return confRegistry;
+ return registry;
}
}
diff --git a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationRegistry.java b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationRegistry.java
index bb0935f..8ef663e 100644
--- a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationRegistry.java
+++ b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationRegistry.java
@@ -22,6 +22,7 @@ import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -29,7 +30,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import org.apache.ignite.configuration.ConfigurationTree;
import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.validation.Immutable;
import org.apache.ignite.configuration.validation.Max;
import org.apache.ignite.configuration.validation.Min;
@@ -48,10 +48,9 @@ import org.apache.ignite.internal.configuration.validation.MaxValidator;
import org.apache.ignite.internal.configuration.validation.MinValidator;
import org.apache.ignite.internal.manager.IgniteComponent;
import org.apache.ignite.lang.IgniteLogger;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.configuration.util.ConfigurationNotificationsUtil.notifyListeners;
+import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.checkConfigurationType;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.innerNodeVisitor;
/** */
@@ -65,16 +64,10 @@ public class ConfigurationRegistry implements IgniteComponent {
/** Root keys. */
private final Collection<RootKey<?, ?>> rootKeys;
- /** Validators. */
- private final Map<Class<? extends Annotation>, Set<Validator<? extends Annotation, ?>>> validators;
+ /** Configuration change handler. */
+ private final ConfigurationChanger changer;
- /** Configuration storages. */
- private final Collection<ConfigurationStorage> configurationStorages;
-
- /** */
- private volatile ConfigurationChanger changer;
-
- /** */
+ /** Configuration generator. */
private final ConfigurationAsmGenerator cgen = new ConfigurationAsmGenerator();
/**
@@ -82,44 +75,43 @@ public class ConfigurationRegistry implements IgniteComponent {
*
* @param rootKeys Configuration root keys.
* @param validators Validators.
- * @param configurationStorages Configuration Storages.
+ * @param storage Configuration storage.
+ * @throws IllegalArgumentException If the configuration type of the root keys is not equal to the storage type.
*/
public ConfigurationRegistry(
Collection<RootKey<?, ?>> rootKeys,
Map<Class<? extends Annotation>, Set<Validator<? extends Annotation, ?>>> validators,
- Collection<ConfigurationStorage> configurationStorages
+ ConfigurationStorage storage
) {
+ checkConfigurationType(rootKeys, storage);
+
this.rootKeys = rootKeys;
- this.validators = validators;
- this.configurationStorages = configurationStorages;
- }
- /** {@inheritDoc} */
- @Override public void start() {
- this.changer = new ConfigurationChanger(this::notificator) {
+ Map<Class<? extends Annotation>, Set<Validator<?, ?>>> validators0 = new HashMap<>(validators);
+
+ validators0.computeIfAbsent(Min.class, a -> new HashSet<>()).add(new MinValidator());
+ validators0.computeIfAbsent(Max.class, a -> new HashSet<>()).add(new MaxValidator());
+ validators0.computeIfAbsent(Immutable.class, a -> new HashSet<>()).add(new ImmutableValidator());
+
+ changer = new ConfigurationChanger(this::notificator, rootKeys, validators0, storage) {
/** {@inheritDoc} */
@Override public InnerNode createRootNode(RootKey<?, ?> rootKey) {
return cgen.instantiateNode(rootKey.schemaClass());
}
};
+ }
- changer.addValidator(Min.class, new MinValidator());
- changer.addValidator(Max.class, new MaxValidator());
- changer.addValidator(Immutable.class, new ImmutableValidator());
-
+ /** {@inheritDoc} */
+ @Override public void start() {
rootKeys.forEach(rootKey -> {
cgen.compileRootSchema(rootKey.schemaClass());
- changer.addRootKey(rootKey);
-
DynamicConfiguration<?, ?> cfg = cgen.instantiateCfg(rootKey, changer);
configs.put(rootKey.key(), cfg);
});
- validators.forEach(changer::addValidators);
-
- configurationStorages.forEach(changer::register);
+ changer.start();
}
/** {@inheritDoc} */
@@ -129,16 +121,12 @@ public class ConfigurationRegistry implements IgniteComponent {
}
/**
- * Starts storage configurations.
- * @param storageType Storage type.
+ * Initializes the configuration storage - reads data and sets default values for missing configuration properties.
*/
- public void startStorageConfigurations(ConfigurationType storageType) {
- changer.initialize(storageType);
+ public void initializeDefaults() {
+ changer.initializeDefaults();
for (RootKey<?, ?> rootKey : rootKeys) {
- if (rootKey.type() != storageType)
- continue;
-
DynamicConfiguration<?, ?> dynCfg = configs.get(rootKey.key());
ConfigurationNotificationsUtil.touch(dynCfg);
@@ -147,6 +135,7 @@ public class ConfigurationRegistry implements IgniteComponent {
/**
* Gets the public configuration tree.
+ *
* @param rootKey Root key.
* @param <V> View type.
* @param <C> Change type.
@@ -167,11 +156,11 @@ public class ConfigurationRegistry implements IgniteComponent {
* @throws IllegalArgumentException If {@code path} is not found in current configuration.
*/
public <T> T represent(List<String> path, ConfigurationVisitor<T> visitor) throws IllegalArgumentException {
- SuperRoot mergedSuperRoot = changer.mergedSuperRoot();
+ SuperRoot superRoot = changer.superRoot();
Object node;
try {
- node = ConfigurationUtil.find(path, mergedSuperRoot);
+ node = ConfigurationUtil.find(path, superRoot);
}
catch (KeyNotFoundException e) {
throw new IllegalArgumentException(e.getMessage());
@@ -187,20 +176,27 @@ public class ConfigurationRegistry implements IgniteComponent {
/**
* Change configuration.
- * @param changesSource Configuration source to create patch from it.
- * @param storage Expected storage for the changes. Can be null, this will mean that derived storage will be used
- * unconditionaly.
+ *
+ * @param changesSrc Configuration source to create patch from it.
* @return Future that is completed on change completion.
*/
- public CompletableFuture<Void> change(ConfigurationSource changesSource, @Nullable ConfigurationStorage storage) {
- return changer.change(changesSource, storage);
+ public CompletableFuture<Void> change(ConfigurationSource changesSrc) {
+ return changer.change(changesSrc);
}
- /** */
- private @NotNull CompletableFuture<Void> notificator(SuperRoot oldSuperRoot, SuperRoot newSuperRoot, long storageRevision) {
+ /**
+ * Configuration change notifier.
+ *
+ * @param oldSuperRoot Old roots values. All these roots always belong to a single storage.
+ * @param newSuperRoot New values for the same roots as in {@code oldRoot}.
+ * @param storageRevision Revision of the storage.
+ * @return Future that must signify when processing is completed.
+ */
+ private CompletableFuture<Void> notificator(SuperRoot oldSuperRoot, SuperRoot newSuperRoot, long storageRevision) {
List<CompletableFuture<?>> futures = new ArrayList<>();
newSuperRoot.traverseChildren(new ConfigurationVisitor<Void>() {
+ /** {@inheritDoc} */
@Override public Void visitInnerNode(String key, InnerNode newRoot) {
InnerNode oldRoot = oldSuperRoot.traverseChild(key, innerNodeVisitor());
@@ -215,15 +211,13 @@ public class ConfigurationRegistry implements IgniteComponent {
}
});
- // Map futures into a "suppressed" future that won't throw any exceptions on completion.
- Function<CompletableFuture<?>, CompletableFuture<?>> mapping = fut -> fut.handle((res, throwable) -> {
+ // Map futures is only for logging errors.
+ Function<CompletableFuture<?>, CompletableFuture<?>> mapping = fut -> fut.whenComplete((res, throwable) -> {
if (throwable != null)
LOG.error("Failed to notify configuration listener.", throwable);
-
- return res;
});
- CompletableFuture[] resultFutures = futures.stream().map(mapping).toArray(CompletableFuture[]::new);
+ CompletableFuture<?>[] resultFutures = futures.stream().map(mapping).toArray(CompletableFuture[]::new);
return CompletableFuture.allOf(resultFutures);
}
diff --git a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicConfiguration.java b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicConfiguration.java
index 94b7eee..010f34d 100644
--- a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicConfiguration.java
+++ b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicConfiguration.java
@@ -88,7 +88,7 @@ public abstract class DynamicConfiguration<VIEW, CHANGE> extends ConfigurationNo
};
// Use resulting tree as update request for the storage.
- return changer.change(src, null);
+ return changer.change(src);
}
/** {@inheritDoc} */
diff --git a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicProperty.java b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicProperty.java
index 6f4b85d..769c489 100644
--- a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicProperty.java
+++ b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/DynamicProperty.java
@@ -82,7 +82,7 @@ public class DynamicProperty<T extends Serializable> extends ConfigurationNode<T
};
// Use resulting tree as update request for the storage.
- return changer.change(src, null);
+ return changer.change(src);
}
/** {@inheritDoc} */
diff --git a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
index 5b33d68..8c1cdb5 100644
--- a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
+++ b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.configuration.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,6 +28,8 @@ import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.stream.Collectors;
import org.apache.ignite.configuration.NamedListView;
+import org.apache.ignite.configuration.RootKey;
+import org.apache.ignite.internal.configuration.storage.ConfigurationStorage;
import org.apache.ignite.internal.configuration.tree.ConfigurationSource;
import org.apache.ignite.internal.configuration.tree.ConfigurationVisitor;
import org.apache.ignite.internal.configuration.tree.ConstructableTreeNode;
@@ -502,4 +505,18 @@ public class ConfigurationUtil {
}
};
}
+
+ /**
+ * Checks that the configuration type of root keys is equal to the storage type.
+ *
+ * @throws IllegalArgumentException If the configuration type of the root keys is not equal to the storage type.
+ */
+ public static void checkConfigurationType(Collection<RootKey<?, ?>> rootKeys, ConfigurationStorage storage) {
+ for (RootKey<?, ?> key : rootKeys) {
+ if (key.type() != storage.type()) {
+ throw new IllegalArgumentException("Invalid root key configuration type [key=" + key +
+ ", storage=" + storage.getClass().getName() + ", storageType=" + storage.type() + "]");
+ }
+ }
+ }
}
diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java b/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java
index 6849c5e..59d18d1 100644
--- a/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java
+++ b/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java
@@ -18,7 +18,6 @@
package org.apache.ignite.rest;
import java.net.BindException;
-import java.nio.charset.StandardCharsets;
import java.util.Map;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@@ -28,7 +27,6 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.apache.ignite.configuration.schemas.rest.RestConfiguration;
@@ -39,12 +37,16 @@ import org.apache.ignite.internal.configuration.ConfigurationRegistry;
import org.apache.ignite.internal.manager.IgniteComponent;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.lang.IgniteLogger;
+import org.apache.ignite.rest.netty.RestApiHttpRequest;
+import org.apache.ignite.rest.netty.RestApiHttpResponse;
import org.apache.ignite.rest.netty.RestApiInitializer;
import org.apache.ignite.rest.presentation.ConfigurationPresentation;
import org.apache.ignite.rest.presentation.hocon.HoconPresentation;
import org.apache.ignite.rest.routes.Router;
+import static io.netty.handler.codec.http.HttpHeaderValues.APPLICATION_JSON;
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
+import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Rest module is responsible for starting a REST endpoints for accessing and managing configuration.
@@ -53,90 +55,89 @@ import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
* Refer to default config file in resources for the example.
*/
public class RestModule implements IgniteComponent {
- /** */
+ /** Default port. */
public static final int DFLT_PORT = 10300;
- /** */
- private static final String CONF_URL = "/management/v1/configuration/";
+ /** Node configuration route. */
+ private static final String NODE_CFG_URL = "/management/v1/configuration/node/";
- /** */
+ /** Cluster configuration route. */
+ private static final String CLUSTER_CFG_URL = "/management/v1/configuration/cluster/";
+
+ /** Path parameter. */
private static final String PATH_PARAM = "selector";
/** Ignite logger. */
private final IgniteLogger LOG = IgniteLogger.forClass(RestModule.class);
- /** */
- private final ConfigurationRegistry sysConf;
+ /** Node configuration register. */
+ private final ConfigurationRegistry nodeCfgRegistry;
+
+ /** Presentation of node configuration. */
+ private final ConfigurationPresentation<String> nodeCfgPresentation;
- /** */
- private volatile ConfigurationPresentation<String> presentation;
+ /** Presentation of cluster configuration. */
+ private final ConfigurationPresentation<String> clusterCfgPresentation;
/**
* Creates a new instance of REST module.
*
* @param nodeCfgMgr Node configuration manager.
+ * @param clusterCfgMgr Cluster configuration manager.
*/
- public RestModule(ConfigurationManager nodeCfgMgr) {
- sysConf = nodeCfgMgr.configurationRegistry();
+ public RestModule(
+ ConfigurationManager nodeCfgMgr,
+ ConfigurationManager clusterCfgMgr
+ ) {
+ nodeCfgRegistry = nodeCfgMgr.configurationRegistry();
+
+ nodeCfgPresentation = new HoconPresentation(nodeCfgMgr.configurationRegistry());
+ clusterCfgPresentation = new HoconPresentation(clusterCfgMgr.configurationRegistry());
}
/** {@inheritDoc} */
@Override public void start() {
- presentation = new HoconPresentation(sysConf);
-
var router = new Router();
router
- .get(CONF_URL, (req, resp) -> {
- resp.json(presentation.represent());
- })
- .get(CONF_URL + ":" + PATH_PARAM, (req, resp) -> {
- String cfgPath = req.queryParams().get(PATH_PARAM);
- try {
- resp.json(presentation.representByPath(cfgPath));
- }
- catch (IllegalArgumentException pathE) {
- ErrorResult eRes = new ErrorResult("CONFIG_PATH_UNRECOGNIZED", pathE.getMessage());
-
- resp.status(BAD_REQUEST);
- resp.json(Map.of("error", eRes));
- }
- })
- .put(CONF_URL, HttpHeaderValues.APPLICATION_JSON, (req, resp) -> {
- try {
- presentation.update(
- req
- .request()
- .content()
- .readCharSequence(req.request().content().readableBytes(), StandardCharsets.UTF_8)
- .toString());
- }
- catch (IllegalArgumentException e) {
- ErrorResult eRes = new ErrorResult("INVALID_CONFIG_FORMAT", e.getMessage());
-
- resp.status(BAD_REQUEST);
- resp.json(Map.of("error", eRes));
- }
- catch (ConfigurationValidationException e) {
- ErrorResult eRes = new ErrorResult("VALIDATION_EXCEPTION", e.getMessage());
-
- resp.status(BAD_REQUEST);
- resp.json(Map.of("error", eRes));
- }
- catch (IgniteException e) {
- ErrorResult eRes = new ErrorResult("APPLICATION_EXCEPTION", e.getMessage());
-
- resp.status(BAD_REQUEST);
- resp.json(Map.of("error", eRes));
- }
- });
+ .get(
+ NODE_CFG_URL,
+ (req, resp) -> resp.json(nodeCfgPresentation.represent())
+ )
+ .get(
+ CLUSTER_CFG_URL,
+ (req, resp) -> resp.json(clusterCfgPresentation.represent())
+ )
+ .get(
+ NODE_CFG_URL + ":" + PATH_PARAM,
+ (req, resp) -> handleRepresentByPath(req, resp, nodeCfgPresentation)
+ )
+ .get(
+ CLUSTER_CFG_URL + ":" + PATH_PARAM,
+ (req, resp) -> handleRepresentByPath(req, resp, clusterCfgPresentation)
+ )
+ .put(
+ NODE_CFG_URL,
+ APPLICATION_JSON,
+ (req, resp) -> handleUpdate(req, resp, nodeCfgPresentation)
+ )
+ .put(
+ CLUSTER_CFG_URL,
+ APPLICATION_JSON,
+ (req, resp) -> handleUpdate(req, resp, clusterCfgPresentation)
+ );
startRestEndpoint(router);
}
- /** */
+ /**
+ * Start endpoint.
+ *
+ * @param router Dispatcher of http requests.
+ * @return Future which will be notified when this channel is closed.
+ */
private ChannelFuture startRestEndpoint(Router router) {
- RestView restConfigurationView = sysConf.getConfiguration(RestConfiguration.KEY).value();
+ RestView restConfigurationView = nodeCfgRegistry.getConfiguration(RestConfiguration.KEY).value();
int desiredPort = restConfigurationView.port();
int portRange = restConfigurationView.portRange();
@@ -151,31 +152,36 @@ public class RestModule implements IgniteComponent {
var hnd = new RestApiInitializer(router);
// TODO: IGNITE-15132 Rest module must reuse netty infrastructure from network module
- ServerBootstrap b = new ServerBootstrap();
- b.option(ChannelOption.SO_BACKLOG, 1024);
- b.group(parentGrp, childGrp)
+ ServerBootstrap b = new ServerBootstrap()
+ .option(ChannelOption.SO_BACKLOG, 1024)
+ .group(parentGrp, childGrp)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(hnd);
for (int portCandidate = desiredPort; portCandidate <= desiredPort + portRange; portCandidate++) {
ChannelFuture bindRes = b.bind(portCandidate).awaitUninterruptibly();
+
if (bindRes.isSuccess()) {
ch = bindRes.channel();
ch.closeFuture().addListener(new ChannelFutureListener() {
+ /** {@inheritDoc} */
@Override public void operationComplete(ChannelFuture fut) {
parentGrp.shutdownGracefully();
childGrp.shutdownGracefully();
+
LOG.error("REST component was stopped", fut.cause());
}
});
+
port = portCandidate;
break;
}
else if (!(bindRes.cause() instanceof BindException)) {
parentGrp.shutdownGracefully();
childGrp.shutdownGracefully();
+
throw new RuntimeException(bindRes.cause());
}
}
@@ -192,7 +198,8 @@ public class RestModule implements IgniteComponent {
throw new RuntimeException(msg);
}
- LOG.info("REST protocol started successfully on port " + port);
+ if (LOG.isInfoEnabled())
+ LOG.info("REST protocol started successfully on port " + port);
return ch.closeFuture();
}
@@ -200,4 +207,70 @@ public class RestModule implements IgniteComponent {
/** {@inheritDoc} */
@Override public void stop() throws Exception {
}
+
+ /**
+ * Handle a request to get the configuration by {@link #PATH_PARAM path}.
+ *
+ * @param req Rest request.
+ * @param res Rest response.
+ * @param presentation Configuration presentation.
+ */
+ private void handleRepresentByPath(
+ RestApiHttpRequest req,
+ RestApiHttpResponse res,
+ ConfigurationPresentation<String> presentation
+ ) {
+ try {
+ String cfgPath = req.queryParams().get(PATH_PARAM);
+
+ res.json(presentation.representByPath(cfgPath));
+ }
+ catch (IllegalArgumentException pathE) {
+ ErrorResult eRes = new ErrorResult("CONFIG_PATH_UNRECOGNIZED", pathE.getMessage());
+
+ res.status(BAD_REQUEST);
+ res.json(Map.of("error", eRes));
+ }
+ }
+
+ /**
+ * Handle a configuration update request as json.
+ *
+ * @param req Rest request.
+ * @param res Rest response.
+ * @param presentation Configuration presentation.
+ */
+ private void handleUpdate(
+ RestApiHttpRequest req,
+ RestApiHttpResponse res,
+ ConfigurationPresentation<String> presentation
+ ) {
+ try {
+ String updateReq = req
+ .request()
+ .content()
+ .readCharSequence(req.request().content().readableBytes(), UTF_8)
+ .toString();
+
+ presentation.update(updateReq);
+ }
+ catch (IllegalArgumentException e) {
+ ErrorResult eRes = new ErrorResult("INVALID_CONFIG_FORMAT", e.getMessage());
+
+ res.status(BAD_REQUEST);
+ res.json(Map.of("error", eRes));
+ }
+ catch (ConfigurationValidationException e) {
+ ErrorResult eRes = new ErrorResult("VALIDATION_EXCEPTION", e.getMessage());
+
+ res.status(BAD_REQUEST);
+ res.json(Map.of("error", eRes));
+ }
+ catch (IgniteException e) {
+ ErrorResult eRes = new ErrorResult("APPLICATION_EXCEPTION", e.getMessage());
+
+ res.status(BAD_REQUEST);
+ res.json(Map.of("error", eRes));
+ }
+ }
}
diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/presentation/hocon/HoconPresentation.java b/modules/rest/src/main/java/org/apache/ignite/rest/presentation/hocon/HoconPresentation.java
index 9f6d5bf..88329c5 100644
--- a/modules/rest/src/main/java/org/apache/ignite/rest/presentation/hocon/HoconPresentation.java
+++ b/modules/rest/src/main/java/org/apache/ignite/rest/presentation/hocon/HoconPresentation.java
@@ -62,7 +62,7 @@ public class HoconPresentation implements ConfigurationPresentation<String> {
throw new IllegalArgumentException("Empty configuration");
try {
- registry.change(HoconConverter.hoconSource(parseString(cfgUpdate).root()), null).get();
+ registry.change(HoconConverter.hoconSource(parseString(cfgUpdate).root())).get();
}
catch (IllegalArgumentException | ConfigurationValidationException e) {
throw e;
diff --git a/modules/rest/src/test/java/org/apache/ignite/rest/presentation/ConfigurationPresentationTest.java b/modules/rest/src/test/java/org/apache/ignite/rest/presentation/ConfigurationPresentationTest.java
index 951110c..d54669e 100644
--- a/modules/rest/src/test/java/org/apache/ignite/rest/presentation/ConfigurationPresentationTest.java
+++ b/modules/rest/src/test/java/org/apache/ignite/rest/presentation/ConfigurationPresentationTest.java
@@ -70,7 +70,7 @@ public class ConfigurationPresentationTest {
cfgRegistry = new ConfigurationRegistry(
List.of(TestRootConfiguration.KEY),
Map.of(Value.class, Set.of(validator)),
- List.of(new TestConfigurationStorage(LOCAL))
+ new TestConfigurationStorage(LOCAL)
);
cfgRegistry.start();
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/storage/ITDistributedConfigurationStorageTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/storage/ITDistributedConfigurationStorageTest.java
index 88df9de..b7c5646 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/storage/ITDistributedConfigurationStorageTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/storage/ITDistributedConfigurationStorageTest.java
@@ -24,10 +24,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.runner.NodeConfiguration;
import org.apache.ignite.internal.configuration.ConfigurationManager;
-import org.apache.ignite.internal.configuration.storage.ConfigurationStorage;
import org.apache.ignite.internal.configuration.storage.Data;
import org.apache.ignite.internal.manager.IgniteComponent;
import org.apache.ignite.internal.metastorage.MetaStorageManager;
@@ -94,9 +92,11 @@ public class ITDistributedConfigurationStorageTest {
List<RootKey<?, ?>> rootKeys = List.of(NodeConfiguration.KEY);
- List<ConfigurationStorage> localStorage = List.of(new LocalConfigurationStorage(vaultManager));
-
- cfgManager = new ConfigurationManager(rootKeys, localStorage);
+ cfgManager = new ConfigurationManager(
+ rootKeys,
+ Map.of(),
+ new LocalConfigurationStorage(vaultManager)
+ );
metaStorageManager = new MetaStorageManager(
vaultManager,
@@ -131,7 +131,7 @@ public class ITDistributedConfigurationStorageTest {
// metastorage configuration
var config = String.format("{\"node\": {\"metastorageNodes\": [ \"%s\" ]}}", addr);
- cfgManager.bootstrap(config, ConfigurationType.LOCAL);
+ cfgManager.bootstrap(config);
Stream.of(clusterService, raftManager, metaStorageManager).forEach(IgniteComponent::start);
diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java
index a3407f2..8836dd5 100644
--- a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java
+++ b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java
@@ -24,32 +24,31 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.ignite.app.Ignite;
import org.apache.ignite.app.Ignition;
import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.network.NetworkConfiguration;
import org.apache.ignite.configuration.schemas.network.NetworkView;
import org.apache.ignite.configuration.schemas.rest.RestConfiguration;
import org.apache.ignite.configuration.schemas.runner.ClusterConfiguration;
import org.apache.ignite.configuration.schemas.runner.NodeConfiguration;
+import org.apache.ignite.configuration.schemas.table.TableValidator;
import org.apache.ignite.configuration.schemas.table.TablesConfiguration;
import org.apache.ignite.internal.affinity.AffinityManager;
import org.apache.ignite.internal.baseline.BaselineManager;
import org.apache.ignite.internal.configuration.ConfigurationManager;
-import org.apache.ignite.internal.configuration.storage.ConfigurationStorage;
import org.apache.ignite.internal.manager.IgniteComponent;
import org.apache.ignite.internal.metastorage.MetaStorageManager;
import org.apache.ignite.internal.processors.query.calcite.SqlQueryProcessor;
import org.apache.ignite.internal.raft.Loza;
import org.apache.ignite.internal.schema.SchemaManager;
+import org.apache.ignite.internal.schema.configuration.SchemaTableValidatorImpl;
import org.apache.ignite.internal.storage.DistributedConfigurationStorage;
import org.apache.ignite.internal.storage.LocalConfigurationStorage;
import org.apache.ignite.internal.table.distributed.TableManager;
@@ -208,37 +207,36 @@ public class IgnitionImpl implements Ignition {
vaultMgr.putName(nodeName).join();
- List<RootKey<?, ?>> rootKeys = Arrays.asList(
+ List<RootKey<?, ?>> nodeRootKeys = List.of(
NetworkConfiguration.KEY,
NodeConfiguration.KEY,
- ClusterConfiguration.KEY,
- TablesConfiguration.KEY,
RestConfiguration.KEY
);
- List<ConfigurationStorage> cfgStorages =
- new ArrayList<>(Collections.singletonList(new LocalConfigurationStorage(vaultMgr)));
-
// Bootstrap node configuration manager.
- ConfigurationManager nodeConfigurationMgr = doStartComponent(
+ ConfigurationManager nodeCfgMgr = doStartComponent(
nodeName,
startedComponents,
- new ConfigurationManager(rootKeys, cfgStorages)
+ new ConfigurationManager(
+ nodeRootKeys,
+ Map.of(),
+ new LocalConfigurationStorage(vaultMgr)
+ )
);
if (cfgContent != null) {
try {
- nodeConfigurationMgr.bootstrap(cfgContent, ConfigurationType.LOCAL);
+ nodeCfgMgr.bootstrap(cfgContent);
}
catch (Exception e) {
LOG.warn("Unable to parse user-specific configuration, default configuration will be used: {}", e.getMessage());
}
}
else
- nodeConfigurationMgr.configurationRegistry().startStorageConfigurations(ConfigurationType.LOCAL);
+ nodeCfgMgr.configurationRegistry().initializeDefaults();
NetworkView netConfigurationView =
- nodeConfigurationMgr.configurationRegistry().getConfiguration(NetworkConfiguration.KEY).value();
+ nodeCfgMgr.configurationRegistry().getConfiguration(NetworkConfiguration.KEY).value();
var serializationRegistry = new MessageSerializationRegistryImpl();
@@ -271,20 +269,28 @@ public class IgnitionImpl implements Ignition {
startedComponents,
new MetaStorageManager(
vaultMgr,
- nodeConfigurationMgr,
+ nodeCfgMgr,
clusterNetSvc,
raftMgr
)
);
// TODO IGNITE-14578 Bootstrap configuration manager with distributed configuration.
- cfgStorages.add(new DistributedConfigurationStorage(metaStorageMgr, vaultMgr));
+
+ List<RootKey<?, ?>> clusterRootKeys = List.of(
+ ClusterConfiguration.KEY,
+ TablesConfiguration.KEY
+ );
// Start cluster configuration manager.
- ConfigurationManager clusterConfigurationMgr = doStartComponent(
+ ConfigurationManager clusterCfgMgr = doStartComponent(
nodeName,
startedComponents,
- new ConfigurationManager(rootKeys, cfgStorages)
+ new ConfigurationManager(
+ clusterRootKeys,
+ Map.of(TableValidator.class, Set.of(SchemaTableValidatorImpl.INSTANCE)),
+ new DistributedConfigurationStorage(metaStorageMgr, vaultMgr)
+ )
);
// Baseline manager startup.
@@ -292,7 +298,7 @@ public class IgnitionImpl implements Ignition {
nodeName,
startedComponents,
new BaselineManager(
- clusterConfigurationMgr,
+ clusterCfgMgr,
metaStorageMgr,
clusterNetSvc
)
@@ -303,7 +309,7 @@ public class IgnitionImpl implements Ignition {
nodeName,
startedComponents,
new AffinityManager(
- clusterConfigurationMgr,
+ clusterCfgMgr,
metaStorageMgr,
baselineMgr
)
@@ -314,7 +320,7 @@ public class IgnitionImpl implements Ignition {
nodeName,
startedComponents,
new SchemaManager(
- clusterConfigurationMgr,
+ clusterCfgMgr,
metaStorageMgr,
vaultMgr
)
@@ -325,7 +331,8 @@ public class IgnitionImpl implements Ignition {
nodeName,
startedComponents,
new TableManager(
- clusterConfigurationMgr,
+ nodeCfgMgr,
+ clusterCfgMgr,
metaStorageMgr,
schemaMgr,
affinityMgr,
@@ -346,7 +353,8 @@ public class IgnitionImpl implements Ignition {
doStartComponent(
nodeName,
startedComponents,
- new RestModule(nodeConfigurationMgr));
+ new RestModule(nodeCfgMgr, clusterCfgMgr)
+ );
// Deploy all resisted watches cause all components are ready and have registered their listeners.
metaStorageMgr.deployWatches();
@@ -375,8 +383,8 @@ public class IgnitionImpl implements Ignition {
nodeName,
distributedTblMgr,
qryProc,
- nodeConfigurationMgr,
- clusterConfigurationMgr
+ nodeCfgMgr,
+ clusterCfgMgr
);
}
catch (Exception e) {
diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java b/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java
index 103fcf2..e119637 100644
--- a/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java
+++ b/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java
@@ -52,7 +52,7 @@ public class LocalConfigurationStorage implements ConfigurationStorage {
private ConfigurationStorageListener lsnr;
/** Storage version. */
- private AtomicLong ver = new AtomicLong(0L);
+ private final AtomicLong ver = new AtomicLong(0L);
/** Start key in range for searching local configuration keys. */
private static final ByteArray LOC_KEYS_START_RANGE = ByteArray.fromString(LOC_PREFIX);
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/SchemaConfigurationConverterTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/SchemaConfigurationConverterTest.java
index 89634d8..4ec9da5 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/SchemaConfigurationConverterTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/SchemaConfigurationConverterTest.java
@@ -19,9 +19,11 @@ package org.apache.ignite.internal.schema.configuration;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.table.TableConfiguration;
import org.apache.ignite.configuration.schemas.table.TableValidator;
import org.apache.ignite.configuration.schemas.table.TablesConfiguration;
@@ -45,6 +47,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -68,13 +71,14 @@ public class SchemaConfigurationConverterTest {
@BeforeEach
public void createRegistry() throws ExecutionException, InterruptedException {
confRegistry = new ConfigurationRegistry(
- Collections.singleton(TablesConfiguration.KEY),
- Collections.singletonMap(TableValidator.class, Collections.singleton(SchemaTableValidatorImpl.INSTANCE)),
- Collections.singleton(new TestConfigurationStorage(ConfigurationType.DISTRIBUTED)));
+ List.of(TablesConfiguration.KEY),
+ Map.of(TableValidator.class, Set.of(SchemaTableValidatorImpl.INSTANCE)),
+ new TestConfigurationStorage(DISTRIBUTED)
+ );
confRegistry.start();
- tblBuilder = SchemaBuilders.tableBuilder("SNAME","TNAME")
+ tblBuilder = SchemaBuilders.tableBuilder("SNAME", "TNAME")
.columns(
SchemaBuilders.column("COL1", ColumnType.DOUBLE).build(),
SchemaBuilders.column("COL2", ColumnType.DOUBLE).build(),
@@ -105,7 +109,7 @@ public class SchemaConfigurationConverterTest {
public void testConvertHashIndex() throws ExecutionException, InterruptedException {
HashIndexBuilder builder = SchemaBuilders.hashIndex("testHI")
.withColumns("A", "B", "C")
- .withHints(Collections.singletonMap("param","value"));
+ .withHints(Collections.singletonMap("param", "value"));
HashIndex idx = builder.build();
getTbl().change(ch -> SchemaConfigurationConverter.addIndex(idx, ch)).get();
diff --git a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
index d1bddb3..28961cd 100644
--- a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
+++ b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
@@ -101,8 +101,11 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
/** Meta storage service. */
private final MetaStorageManager metaStorageMgr;
- /** Configuration manager. */
- private final ConfigurationManager configurationMgr;
+ /** Node configuration manager. */
+ private final ConfigurationManager nodeCfgMgr;
+
+ /** Cluster configuration manager. */
+ private final ConfigurationManager clusterCfgMgr;
/** Raft manager. */
private final Loza raftMgr;
@@ -125,7 +128,8 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
/**
* Creates a new table manager.
*
- * @param configurationMgr Configuration manager.
+ * @param nodeCfgMgr Node configuration manager.
+ * @param clusterCfgMgr Cluster configuration manager.
* @param metaStorageMgr Meta storage manager.
* @param schemaMgr Schema manager.
* @param affMgr Affinity manager.
@@ -133,14 +137,16 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
* @param partitionsStoreDir Partitions store directory.
*/
public TableManager(
- ConfigurationManager configurationMgr,
+ ConfigurationManager nodeCfgMgr,
+ ConfigurationManager clusterCfgMgr,
MetaStorageManager metaStorageMgr,
SchemaManager schemaMgr,
AffinityManager affMgr,
Loza raftMgr,
Path partitionsStoreDir
) {
- this.configurationMgr = configurationMgr;
+ this.nodeCfgMgr = nodeCfgMgr;
+ this.clusterCfgMgr = clusterCfgMgr;
this.metaStorageMgr = metaStorageMgr;
this.affMgr = affMgr;
this.raftMgr = raftMgr;
@@ -151,7 +157,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
/** {@inheritDoc} */
@Override public void start() {
//TODO: IGNITE-14652 Change a metastorage update in listeners to multi-invoke
- configurationMgr.configurationRegistry().getConfiguration(TablesConfiguration.KEY).tables().listen(ctx -> {
+ clusterCfgMgr.configurationRegistry().getConfiguration(TablesConfiguration.KEY).tables().listen(ctx -> {
return onConfigurationChanged(ctx.storageRevision(), ctx.oldValue(), ctx.newValue());
});
}
@@ -342,7 +348,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
* @return Table creation futures.
*/
private List<CompletableFuture<Boolean>> startTables(Set<String> tbls, long rev, NamedListView<TableView> cfgs) {
- boolean hasMetastorageLocally = metaStorageMgr.hasMetastorageLocally(configurationMgr);
+ boolean hasMetastorageLocally = metaStorageMgr.hasMetastorageLocally(nodeCfgMgr);
List<CompletableFuture<Boolean>> futs = new ArrayList<>();
@@ -426,7 +432,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
* @return Table drop futures.
*/
private List<CompletableFuture<Boolean>> stopTables(Set<String> tbls) {
- boolean hasMetastorageLocally = metaStorageMgr.hasMetastorageLocally(configurationMgr);
+ boolean hasMetastorageLocally = metaStorageMgr.hasMetastorageLocally(nodeCfgMgr);
List<CompletableFuture<Boolean>> futs = new ArrayList<>();
@@ -481,7 +487,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
@NotNull NamedListView<TableView> oldCfg,
@NotNull NamedListView<TableView> newCfg
) {
- boolean hasMetastorageLocally = metaStorageMgr.hasMetastorageLocally(configurationMgr);
+ boolean hasMetastorageLocally = metaStorageMgr.hasMetastorageLocally(nodeCfgMgr);
List<CompletableFuture<Boolean>> futs = new ArrayList<>();
@@ -594,13 +600,14 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
removeListener(TableEvent.CREATE, clo);
} else {
try {
- configurationMgr
- .configurationRegistry()
- .getConfiguration(TablesConfiguration.KEY)
- .tables()
- .change(change -> change.create(name, tableInitChange))
- .get();
- } catch (InterruptedException | ExecutionException e) {
+ clusterCfgMgr
+ .configurationRegistry()
+ .getConfiguration(TablesConfiguration.KEY)
+ .tables()
+ .change(change -> change.create(name, tableInitChange))
+ .get();
+ }
+ catch (InterruptedException | ExecutionException e) {
LOG.error("Table wasn't created [name=" + name + ']', e);
removeListener(TableEvent.CREATE, clo, new IgniteInternalCheckedException(e));
@@ -641,9 +648,9 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
});
try {
- configurationMgr.configurationRegistry()
- .getConfiguration(TablesConfiguration.KEY).tables().change(change ->
- change.createOrUpdate(name, tableChange)).get();
+ clusterCfgMgr.configurationRegistry()
+ .getConfiguration(TablesConfiguration.KEY).tables().change(change ->
+ change.createOrUpdate(name, tableChange)).get();
}
catch (InterruptedException | ExecutionException e) {
LOG.error("Table wasn't created [name=" + name + ']', e);
@@ -698,12 +705,12 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
}
else {
try {
- configurationMgr
- .configurationRegistry()
- .getConfiguration(TablesConfiguration.KEY)
- .tables()
- .change(change -> change.delete(name))
- .get();
+ clusterCfgMgr
+ .configurationRegistry()
+ .getConfiguration(TablesConfiguration.KEY)
+ .tables()
+ .change(change -> change.delete(name))
+ .get();
}
catch (InterruptedException | ExecutionException e) {
LOG.error("Table wasn't dropped [name=" + name + ']', e);
diff --git a/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java b/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
index a4cbb97..d5fa621 100644
--- a/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
+++ b/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
@@ -20,16 +20,14 @@ package org.apache.ignite.internal.table;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Phaser;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.schemas.runner.ClusterConfiguration;
import org.apache.ignite.configuration.schemas.runner.NodeConfiguration;
import org.apache.ignite.configuration.schemas.table.TablesConfiguration;
@@ -76,6 +74,8 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
+import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -121,8 +121,11 @@ public class TableManagerTest {
/** Node name. */
private static final String NODE_NAME = "node1";
- /** Configuration manager. */
- private ConfigurationManager cfrMgr;
+ /** Node configuration manager. */
+ private ConfigurationManager nodeCfgMgr;
+
+ /** Cluster configuration manager. */
+ private ConfigurationManager clusterCfgMgr;
/** MetaStorage manager. */
@Mock(lenient = true)
@@ -154,21 +157,30 @@ public class TableManagerTest {
@BeforeEach
void setUp() {
try {
- cfrMgr = new ConfigurationManager(rootConfigurationKeys(), Arrays.asList(
- new TestConfigurationStorage(ConfigurationType.LOCAL),
- new TestConfigurationStorage(ConfigurationType.DISTRIBUTED)));
+ nodeCfgMgr = new ConfigurationManager(
+ List.of(NodeConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(LOCAL)
+ );
- cfrMgr.start();
+ clusterCfgMgr = new ConfigurationManager(
+ List.of(ClusterConfiguration.KEY, TablesConfiguration.KEY),
+ Map.of(),
+ new TestConfigurationStorage(DISTRIBUTED)
+ );
- cfrMgr.bootstrap("{\n" +
+ nodeCfgMgr.start();
+ clusterCfgMgr.start();
+
+ nodeCfgMgr.bootstrap("{\n" +
" \"node\":{\n" +
" \"metastorageNodes\":[\n" +
" \"" + NODE_NAME + "\"\n" +
" ]\n" +
" }\n" +
- "}", ConfigurationType.LOCAL);
+ "}");
- cfrMgr.bootstrap("{\n" +
+ clusterCfgMgr.bootstrap("{\n" +
" \"cluster\":{\n" +
" \"metastorageNodes\":[\n" +
" \"" + NODE_NAME + "\"\n" +
@@ -205,7 +217,7 @@ public class TableManagerTest {
" }\n" +
" }\n" +
" }\n" +
- "}", ConfigurationType.DISTRIBUTED);
+ "}");
}
catch (Exception e) {
LOG.error("Failed to bootstrap the test configuration manager.", e);
@@ -217,7 +229,8 @@ public class TableManagerTest {
/** Stop configuration manager. */
@AfterEach
void tearDown() {
- cfrMgr.stop();
+ nodeCfgMgr.stop();
+ clusterCfgMgr.stop();
}
/**
@@ -226,7 +239,7 @@ public class TableManagerTest {
@Disabled("https://issues.apache.org/jira/browse/IGNITE-15255")
@Test
public void testStaticTableConfigured() {
- TableManager tableManager = new TableManager(cfrMgr, mm, sm, am, rm, workDir);
+ TableManager tableManager = new TableManager(nodeCfgMgr, clusterCfgMgr, mm, sm, am, rm, workDir);
assertEquals(1, tableManager.tables().size());
@@ -461,7 +474,7 @@ public class TableManagerTest {
return null;
}).when(am).listen(same(AffinityEvent.CALCULATED), any());
- TableManager tableManager = new TableManager(cfrMgr, mm, sm, am, rm, workDir);
+ TableManager tableManager = new TableManager(nodeCfgMgr, clusterCfgMgr, mm, sm, am, rm, workDir);
TableImpl tbl2;
@@ -480,7 +493,7 @@ public class TableManagerTest {
int tablesBeforeCreation = tableManager.tables().size();
- cfrMgr.configurationRegistry().getConfiguration(TablesConfiguration.KEY).tables().listen(ctx -> {
+ clusterCfgMgr.configurationRegistry().getConfiguration(TablesConfiguration.KEY).tables().listen(ctx -> {
boolean createTbl = ctx.newValue().get(schemaTable.canonicalName()) != null &&
ctx.oldValue().get(schemaTable.canonicalName()) == null;
@@ -532,17 +545,4 @@ public class TableManagerTest {
return tbl2;
}
-
- /**
- * Gets a list of configuration keys to use in the test scenario.
- *
- * @return List of root configuration keys.
- */
- private static List<RootKey<?, ?>> rootConfigurationKeys() {
- return Arrays.asList(
- NodeConfiguration.KEY,
- ClusterConfiguration.KEY,
- TablesConfiguration.KEY
- );
- }
}