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 2023/07/20 14:03:37 UTC
[ignite-3] branch main updated: IGNITE-19671 Save default configuration values to configuration storage (#2301)
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 3f89316ace IGNITE-19671 Save default configuration values to configuration storage (#2301)
3f89316ace is described below
commit 3f89316acea9d1ac9763147c14f33ef01090cdae
Author: Cyrill <cy...@gmail.com>
AuthorDate: Thu Jul 20 17:03:31 2023 +0300
IGNITE-19671 Save default configuration values to configuration storage (#2301)
---
.../configuration/ConfigurationChanger.java | 118 ++++++++++++---------
.../configuration/ConfigurationRegistry.java | 18 +---
.../configuration/ConfigurationChangerTest.java | 15 +--
.../asm/ConfigurationTreeGeneratorTest.java | 1 -
.../configuration/direct/DirectPropertiesTest.java | 2 -
.../ConfigurationAnyListenerTest.java | 2 -
.../notifications/ConfigurationListenerTest.java | 4 +-
.../internal/configuration/sample/UsageTest.java | 2 -
.../configuration/tree/InternalIdTest.java | 2 -
...ibutionZoneManagerConfigurationChangesTest.java | 12 +--
.../DistributionZoneManagerScaleUpTest.java | 4 +-
.../DistributionZoneManagerTest.java | 4 +-
.../org/apache/ignite/internal/app/IgniteImpl.java | 2 +-
.../storage/LocalFileConfigurationStorageTest.java | 117 +++++++++++++++++---
.../DdlCommandHandlerExceptionHandlingTest.java | 4 +-
15 files changed, 189 insertions(+), 118 deletions(-)
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 ade0c4b9c4..eb0fed2e2c 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
@@ -49,7 +49,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -95,6 +94,9 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
/** Storage trees. */
private volatile StorageRoots storageRoots;
+ /** Future that resolves after the defaults are persisted to the storage. */
+ private final CompletableFuture<Void> defaultsPersisted = new CompletableFuture<>();
+
/** Configuration listener notification counter, must be incremented before each use of {@link #configurationUpdateListener}. */
private final AtomicLong notificationListenerCnt = new AtomicLong();
@@ -124,6 +126,9 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
* Immutable data container to store version and all roots associated with the specific storage.
*/
private static class StorageRoots {
+ /** Immutable forest, so to say. */
+ private final SuperRoot rootsWithoutDefaults;
+
/** Immutable forest, so to say. */
private final SuperRoot roots;
@@ -136,14 +141,17 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
/**
* Constructor.
*
- * @param roots Forest.
+ * @param rootsWithoutDefaults Forest without the defaults
+ * @param roots Forest with the defaults filled in
* @param version Version associated with the currently known storage state.
*/
- private StorageRoots(SuperRoot roots, long version) {
+ private StorageRoots(SuperRoot rootsWithoutDefaults, SuperRoot roots, long version) {
+ this.rootsWithoutDefaults = rootsWithoutDefaults;
this.roots = roots;
this.version = version;
makeImmutable(roots);
+ makeImmutable(rootsWithoutDefaults);
}
}
@@ -151,7 +159,7 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
* Makes the node immutable by calling {@link ConstructableTreeNode#makeImmutable()} on each sub-node recursively.
*/
private static void makeImmutable(InnerNode node) {
- if (!node.makeImmutable()) {
+ if (node == null || !node.makeImmutable()) {
return;
}
@@ -251,59 +259,56 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
superRoot.addRoot(rootKey, rootNode);
}
- //Workaround for distributed configuration.
+ SuperRoot superRootNoDefaults = superRoot.copy();
+
addDefaults(superRoot);
// Validate the restored configuration.
validateConfiguration(superRoot);
-
- storageRoots = new StorageRoots(superRoot, data.changeId());
+ // We store two configuration roots, one with the defaults set and another one without them.
+ // The root WITH the defaults is used when we calculate who to notify of a configuration change or
+ // when we provide the configuration outside.
+ // The root WITHOUT the defaults is used to calculate which properties to write to the underlying storage,
+ // in other words it allows us to persist the defaults from the code.
+ // After the storage listener fires for the first time both roots are supposed to become equal.
+ storageRoots = new StorageRoots(superRootNoDefaults, superRoot, data.changeId());
storage.registerConfigurationListener(configurationStorageListener());
+
+ persistDefaults();
}
/**
- * Initializes the configuration storage - reads data and sets default values for missing configuration properties.
+ * Persists default values to the storage.
*
- * @throws ConfigurationValidationException If configuration validation failed.
- * @throws ConfigurationChangeException If configuration framework failed to add default values and save them to storage.
+ * <p>Specifically, this method runs a check whether there are
+ * default values that are not persisted to the storage and writes them if there are any.
*/
- public void initializeDefaults() throws ConfigurationValidationException, ConfigurationChangeException {
- try {
- ConfigurationSource defaultsCfgSource = new ConfigurationSource() {
- /** {@inheritDoc} */
- @Override
- public void descend(ConstructableTreeNode node) {
- addDefaults((InnerNode) node);
- }
- };
-
- changeInternally(defaultsCfgSource).get(5, TimeUnit.SECONDS);
- } catch (ExecutionException e) {
- Throwable cause = e.getCause();
-
- if (cause instanceof ConfigurationValidationException) {
- throw (ConfigurationValidationException) cause;
- }
-
- if (cause instanceof ConfigurationChangeException) {
- throw (ConfigurationChangeException) cause;
- }
-
- throw new ConfigurationChangeException(
- "Failed to write default configuration values into the storage " + storage.getClass(), e
- );
- } catch (InterruptedException | TimeoutException e) {
- throw new ConfigurationChangeException(
- "Failed to initialize configuration storage " + storage.getClass(), e
- );
- }
+ private void persistDefaults() {
+ changeInternally(ConfigurationUtil.EMPTY_CFG_SRC, true)
+ .whenComplete((v, e) -> {
+ if (e == null) {
+ defaultsPersisted.complete(null);
+ } else {
+ defaultsPersisted.completeExceptionally(e);
+ }
+ });
}
/** {@inheritDoc} */
@Override
public CompletableFuture<Void> change(ConfigurationSource source) {
- return changeInternally(source);
+ if (storageRoots == null) {
+ throw new ComponentNotStartedException();
+ }
+ return defaultsPersisted.thenCompose(v -> changeInternally(source, false));
+ }
+
+ /**
+ * Returns a future that resolves after the defaults are persisted to the storage.
+ */
+ public CompletableFuture<Void> onDefaultsPersisted() {
+ return defaultsPersisted;
}
/** {@inheritDoc} */
@@ -474,6 +479,8 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
public void stop() {
IgniteUtils.shutdownAndAwaitTermination(pool, 10, TimeUnit.SECONDS);
+ defaultsPersisted.completeExceptionally(new NodeStoppingException());
+
StorageRoots roots = storageRoots;
if (roots != null) {
@@ -509,19 +516,16 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
* Entry point for configuration changes.
*
* @param src Configuration source.
+ * @param onStartup if {@code true} this change is triggered right after startup
* @return Future that will be completed after changes are written to the storage.
* @throws ComponentNotStartedException if changer is not started.
*/
- private CompletableFuture<Void> changeInternally(ConfigurationSource src) {
- if (storageRoots == null) {
- throw new ComponentNotStartedException();
- }
-
+ private CompletableFuture<Void> changeInternally(ConfigurationSource src, boolean onStartup) {
return storage.lastRevision()
.thenComposeAsync(storageRevision -> {
assert storageRevision != null;
- return changeInternally0(src, storageRevision);
+ return changeInternally0(src, storageRevision, onStartup);
}, pool)
.exceptionally(throwable -> {
Throwable cause = throwable.getCause();
@@ -539,10 +543,11 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
*
* @param src Configuration source.
* @param storageRevision Latest storage revision from the metastorage.
+ * @param onStartup if {@code true} this change is triggered right after startup
* @return Future that will be completed after changes are written to the storage.
*/
- private CompletableFuture<Void> changeInternally0(ConfigurationSource src, long storageRevision) {
- // Read lock protects "storageRoots" field from being updated, thus guaranteeing a thread-safe read of configuration inside of the
+ private CompletableFuture<Void> changeInternally0(ConfigurationSource src, long storageRevision, boolean onStartup) {
+ // Read lock protects "storageRoots" field from being updated, thus guaranteeing a thread-safe read of configuration inside the
// change closure.
rwLock.readLock().lock();
@@ -553,7 +558,7 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
if (localRoots.version < storageRevision) {
// Need to wait for the configuration updates from the storage, then try to update again (loop).
- return localRoots.changeFuture.thenCompose(v -> changeInternally(src));
+ return localRoots.changeFuture.thenCompose(v -> changeInternally(src, onStartup));
}
SuperRoot curRoots = localRoots.roots;
@@ -566,7 +571,11 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
addDefaults(changes);
- Map<String, Serializable> allChanges = createFlattenedUpdatesMap(curRoots, changes);
+ Map<String, Serializable> allChanges = createFlattenedUpdatesMap(localRoots.rootsWithoutDefaults, changes);
+ if (allChanges.isEmpty() && onStartup) {
+ // We don't want an empty storage update if this is the initialization changer.
+ return CompletableFuture.completedFuture(null);
+ }
dropNulls(changes);
@@ -583,7 +592,7 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
} else {
// Here we go to next iteration of an implicit spin loop; we have to do it via recursion
// because we work with async code (futures).
- return localRoots.changeFuture.thenCompose(v -> changeInternally(src));
+ return localRoots.changeFuture.thenCompose(v -> changeInternally(src, onStartup));
}
});
} finally {
@@ -613,17 +622,20 @@ public abstract class ConfigurationChanger implements DynamicConfigurationChange
StorageRoots oldStorageRoots = storageRoots;
SuperRoot oldSuperRoot = oldStorageRoots.roots;
+ SuperRoot oldSuperRootNoDefaults = oldStorageRoots.rootsWithoutDefaults;
SuperRoot newSuperRoot = oldSuperRoot.copy();
+ SuperRoot newSuperNoDefaults = oldSuperRootNoDefaults.copy();
Map<String, ?> dataValuesPrefixMap = toPrefixMap(changedEntries.values());
compressDeletedEntries(dataValuesPrefixMap);
fillFromPrefixMap(newSuperRoot, dataValuesPrefixMap);
+ fillFromPrefixMap(newSuperNoDefaults, dataValuesPrefixMap);
long newChangeId = changedEntries.changeId();
- var newStorageRoots = new StorageRoots(newSuperRoot, newChangeId);
+ var newStorageRoots = new StorageRoots(newSuperNoDefaults, newSuperRoot, newChangeId);
rwLock.writeLock().lock();
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 ce12346756..026939af14 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
@@ -21,7 +21,6 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.apache.ignite.internal.configuration.notifications.ConfigurationNotifier.notifyListeners;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.checkConfigurationType;
import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.innerNodeVisitor;
-import static org.apache.ignite.internal.configuration.util.ConfigurationUtil.touch;
import java.io.Serializable;
import java.lang.annotation.Annotation;
@@ -68,9 +67,6 @@ public class ConfigurationRegistry implements IgniteComponent {
/** Generated configuration implementations. Mapping: {@link RootKey#key} -> configuration implementation. */
private final Map<String, DynamicConfiguration<?, ?>> configs = new HashMap<>();
- /** Root keys. */
- private final Collection<RootKey<?, ?>> rootKeys;
-
/** Configuration change handler. */
private final ConfigurationChanger changer;
@@ -92,8 +88,6 @@ public class ConfigurationRegistry implements IgniteComponent {
) {
checkConfigurationType(rootKeys, storage);
- this.rootKeys = rootKeys;
-
changer = new ConfigurationChanger(notificationUpdateListener(), rootKeys, storage, configurationValidator) {
@Override
public InnerNode createRootNode(RootKey<?, ?> rootKey) {
@@ -137,16 +131,10 @@ public class ConfigurationRegistry implements IgniteComponent {
}
/**
- * Initializes the configuration storage - reads data and sets default values for missing configuration properties.
+ * Returns a future that resolves after the defaults are persisted to the storage.
*/
- public void initializeDefaults() {
- changer.initializeDefaults();
-
- for (RootKey<?, ?> rootKey : rootKeys) {
- DynamicConfiguration<?, ?> dynCfg = configs.get(rootKey.key());
-
- touch(dynCfg);
- }
+ public CompletableFuture<Void> onDefaultsPersisted() {
+ return changer.onDefaultsPersisted();
}
/**
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java
index ef821efcb0..7457145a44 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/ConfigurationChangerTest.java
@@ -23,6 +23,7 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.apache.ignite.internal.configuration.FirstConfiguration.KEY;
import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willBe;
+import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anEmptyMap;
@@ -315,8 +316,6 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
-
DefaultsView root = (DefaultsView) changer.getRootNode(DefaultsConfiguration.KEY);
assertEquals("foo", root.defStr());
@@ -344,8 +343,6 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
-
ConfigurationSource source = source(
DefaultsConfiguration.KEY,
(DefaultsChange change) -> change.changeChildrenList(children -> children.create("name", child -> {
@@ -371,8 +368,6 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
-
DefaultsChildView childView = changer.getLatest(List.of(node("def"), node("child")));
assertEquals("bar", childView.defStr());
@@ -396,8 +391,6 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
-
ConfigurationSource source = source(
DefaultsConfiguration.KEY,
(DefaultsChange change) -> change.changeChildrenList(children -> {
@@ -447,8 +440,6 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
-
ConfigurationSource source = source(
DefaultsConfiguration.KEY,
(DefaultsChange change) -> change.changeChildrenList(children -> children.create("name", child -> {
@@ -513,7 +504,7 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
+ assertThat(changer.onDefaultsPersisted(), willCompleteSuccessfully());
assertEquals(1, storage.lastRevision().get(1, SECONDS));
@@ -566,7 +557,7 @@ public class ConfigurationChangerTest {
changer.start();
- changer.initializeDefaults();
+ assertThat(changer.onDefaultsPersisted(), willCompleteSuccessfully());
assertEquals(1, storage.lastRevision().get(1, SECONDS));
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/asm/ConfigurationTreeGeneratorTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/asm/ConfigurationTreeGeneratorTest.java
index d4ab2b1754..89b9c90126 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/asm/ConfigurationTreeGeneratorTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/asm/ConfigurationTreeGeneratorTest.java
@@ -121,7 +121,6 @@ public class ConfigurationTreeGeneratorTest {
);
changer.start();
- changer.initializeDefaults();
}
@AfterEach
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/direct/DirectPropertiesTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/direct/DirectPropertiesTest.java
index 5cad618852..2c79d0df38 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/direct/DirectPropertiesTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/direct/DirectPropertiesTest.java
@@ -112,8 +112,6 @@ public class DirectPropertiesTest {
);
registry.start();
-
- registry.initializeDefaults();
}
@AfterEach
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationAnyListenerTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationAnyListenerTest.java
index 23ba64373e..fe6fdd6133 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationAnyListenerTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationAnyListenerTest.java
@@ -170,8 +170,6 @@ public class ConfigurationAnyListenerTest {
registry.start();
- registry.initializeDefaults();
-
rootConfig = registry.getConfiguration(RootConfiguration.KEY);
// Add "regular" listeners.
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java
index d3862690de..740001f539 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/notifications/ConfigurationListenerTest.java
@@ -31,6 +31,7 @@ import static org.apache.ignite.internal.configuration.notifications.Configurati
import static org.apache.ignite.internal.configuration.notifications.ConfigurationListenerTestUtils.randomUuid;
import static org.apache.ignite.internal.configuration.notifications.ConfigurationNotifier.notifyListeners;
import static org.apache.ignite.internal.testframework.IgniteTestUtils.hasCause;
+import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -178,8 +179,7 @@ public class ConfigurationListenerTest {
);
registry.start();
-
- registry.initializeDefaults();
+ assertThat(registry.onDefaultsPersisted(), willCompleteSuccessfully());
config = registry.getConfiguration(ParentConfiguration.KEY);
}
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java
index 1d7da15616..8cacadf5dc 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/sample/UsageTest.java
@@ -57,8 +57,6 @@ public class UsageTest {
registry.start();
- registry.initializeDefaults();
-
LocalConfiguration root = registry.getConfiguration(LocalConfiguration.KEY);
root.change(local ->
diff --git a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/tree/InternalIdTest.java b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/tree/InternalIdTest.java
index 36de4fd2e4..4aea167549 100644
--- a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/tree/InternalIdTest.java
+++ b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/tree/InternalIdTest.java
@@ -98,8 +98,6 @@ public class InternalIdTest {
);
registry.start();
-
- registry.initializeDefaults();
}
@AfterEach
diff --git a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerConfigurationChangesTest.java b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerConfigurationChangesTest.java
index dc8f0b217d..713ee78a4e 100644
--- a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerConfigurationChangesTest.java
+++ b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerConfigurationChangesTest.java
@@ -180,9 +180,9 @@ public class DistributionZoneManagerConfigurationChangesTest extends IgniteAbstr
assertDataNodesForZoneWithAttributes(1, nodes.stream().map(NodeWithAttributes::node).collect(toSet()), keyValueStorage);
- assertZoneScaleUpChangeTriggerKey(1L, 1, keyValueStorage);
+ assertZoneScaleUpChangeTriggerKey(2L, 1, keyValueStorage);
- assertZonesChangeTriggerKey(1, 1, keyValueStorage);
+ assertZonesChangeTriggerKey(2, 1, keyValueStorage);
}
@Test
@@ -205,10 +205,10 @@ public class DistributionZoneManagerConfigurationChangesTest extends IgniteAbstr
distributionZoneManager.createZone(new DistributionZoneConfigurationParameters.Builder(NEW_ZONE_NAME).build()).get();
- assertZoneScaleUpChangeTriggerKey(1L, 1, keyValueStorage);
- assertZoneScaleUpChangeTriggerKey(2L, 2, keyValueStorage);
- assertZonesChangeTriggerKey(1, 1, keyValueStorage);
- assertZonesChangeTriggerKey(2, 2, keyValueStorage);
+ assertZoneScaleUpChangeTriggerKey(2L, 1, keyValueStorage);
+ assertZoneScaleUpChangeTriggerKey(3L, 2, keyValueStorage);
+ assertZonesChangeTriggerKey(2, 1, keyValueStorage);
+ assertZonesChangeTriggerKey(3, 2, keyValueStorage);
}
@Test
diff --git a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerScaleUpTest.java b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerScaleUpTest.java
index af7e98a271..e262f79101 100644
--- a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerScaleUpTest.java
+++ b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerScaleUpTest.java
@@ -470,7 +470,7 @@ public class DistributionZoneManagerScaleUpTest extends BaseDistributionZoneMana
assertDataNodesForZone(ZONE_1_ID, Set.of(), keyValueStorage);
- assertZoneScaleUpChangeTriggerKey(3L, ZONE_1_ID, keyValueStorage);
+ assertZoneScaleUpChangeTriggerKey(4L, ZONE_1_ID, keyValueStorage);
doAnswer(invocation -> {
If iif = invocation.getArgument(0);
@@ -516,7 +516,7 @@ public class DistributionZoneManagerScaleUpTest extends BaseDistributionZoneMana
assertDataNodesForZone(ZONE_1_ID, Set.of(NODE_1), keyValueStorage);
- assertZoneScaleDownChangeTriggerKey(5L, ZONE_1_ID, keyValueStorage);
+ assertZoneScaleDownChangeTriggerKey(6L, ZONE_1_ID, keyValueStorage);
doAnswer(invocation -> {
If iif = invocation.getArgument(0);
diff --git a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java
index 91fb686962..5bd1324a97 100644
--- a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java
+++ b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java
@@ -23,6 +23,7 @@ import static org.apache.ignite.internal.distributionzones.DistributionZoneManag
import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.IMMEDIATE_TIMER_VALUE;
import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.INFINITE_TIMER_VALUE;
import static org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
+import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -91,8 +92,7 @@ class DistributionZoneManagerTest extends IgniteAbstractTest {
);
registry.start();
-
- registry.initializeDefaults();
+ assertThat(registry.onDefaultsPersisted(), willCompleteSuccessfully());
DistributionZonesConfiguration zonesConfiguration = registry.getConfiguration(DistributionZonesConfiguration.KEY);
diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index 6ba3ece793..d89c111b1a 100644
--- a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++ b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -714,7 +714,6 @@ public class IgniteImpl implements Ignite {
restComponent,
raftMgr,
clusterStateStorage,
- distributedConfigurationUpdater,
cmgMgr
);
@@ -770,6 +769,7 @@ public class IgniteImpl implements Ignite {
return recoverComponentsStateOnStart(startupExecutor);
}, startupExecutor)
+ .thenComposeAsync(v -> clusterCfgMgr.configurationRegistry().onDefaultsPersisted(), startupExecutor)
.thenRunAsync(() -> {
try {
lifecycleManager.startComponent(distributedConfigurationUpdater);
diff --git a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/storage/LocalFileConfigurationStorageTest.java b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/storage/LocalFileConfigurationStorageTest.java
index 30162b0120..88dce5e3a5 100644
--- a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/storage/LocalFileConfigurationStorageTest.java
+++ b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/storage/LocalFileConfigurationStorageTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.configuration.storage;
+import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.aMapWithSize;
import static org.hamcrest.Matchers.allOf;
@@ -93,8 +94,6 @@ public class LocalFileConfigurationStorageTest {
treeGenerator,
new ConfigurationValidatorImpl(treeGenerator, Set.of())
);
-
- changer.start();
}
@AfterEach
@@ -125,6 +124,9 @@ public class LocalFileConfigurationStorageTest {
// And
var topConfiguration = (TopConfiguration) treeGenerator.instantiateCfg(TopConfiguration.KEY, changer);
+ changer.start();
+ assertThat(changer.onDefaultsPersisted(), willCompleteSuccessfully());
+
topConfiguration.namedList().change(b -> b.create("name1", x -> {
x.changeStrVal("strVal1");
x.changeIntVal(-1);
@@ -141,12 +143,21 @@ public class LocalFileConfigurationStorageTest {
// top.namedList.<ids>.name1 -> "<generatedUUID>"
// top.namedList.<generatedUUID>.<order> -> 0
- assertThat(storageValues, allOf(aMapWithSize(5), hasValue(-1)));
- assertThat(storageValues, allOf(aMapWithSize(5), hasValue("strVal1")));
+ assertThat(storageValues, allOf(aMapWithSize(10), hasValue(-1)));
+ assertThat(storageValues, allOf(aMapWithSize(10), hasValue("strVal1")));
// And
+ // Enriched with the defaults
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=-1\n"
@@ -154,6 +165,7 @@ public class LocalFileConfigurationStorageTest {
+ " strVal=strVal1\n"
+ " }\n"
+ " ]\n"
+ + " shortVal=1\n"
+ "}"
));
@@ -166,14 +178,22 @@ public class LocalFileConfigurationStorageTest {
storageValues = readAllLatest();
// Then
- assertThat(storageValues, allOf(aMapWithSize(10), hasValue(-2)));
- assertThat(storageValues, allOf(aMapWithSize(10), hasValue("strVal2")));
+ assertThat(storageValues, allOf(aMapWithSize(15), hasValue(-2)));
+ assertThat(storageValues, allOf(aMapWithSize(15), hasValue("strVal2")));
// And
- assertThat(storageValues, allOf(aMapWithSize(10), hasValue(-1)));
- assertThat(storageValues, allOf(aMapWithSize(10), hasValue("strVal1")));
+ assertThat(storageValues, allOf(aMapWithSize(15), hasValue(-1)));
+ assertThat(storageValues, allOf(aMapWithSize(15), hasValue("strVal1")));
// And
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=-1\n"
@@ -186,6 +206,7 @@ public class LocalFileConfigurationStorageTest {
+ " strVal=strVal2\n"
+ " }\n"
+ " ]\n"
+ + " shortVal=1\n"
+ "}\n"
));
}
@@ -199,15 +220,26 @@ public class LocalFileConfigurationStorageTest {
// When
var topConfiguration = (TopConfiguration) treeGenerator.instantiateCfg(TopConfiguration.KEY, changer);
+ changer.start();
+ assertThat(changer.onDefaultsPersisted(), willCompleteSuccessfully());
+
topConfiguration.shortVal().update((short) 3).get();
// And
var storageValues = readAllLatest();
// Then
- assertThat(storageValues, allOf(aMapWithSize(1), hasValue((short) 3)));
+ assertThat(storageValues, allOf(aMapWithSize(5), hasValue((short) 3)));
// And
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " shortVal=3\n"
+ "}\n"
));
@@ -219,11 +251,19 @@ public class LocalFileConfigurationStorageTest {
storageValues = readAllLatest();
// Then
- assertThat(storageValues, allOf(aMapWithSize(6), hasValue(1)));
- assertThat(storageValues, allOf(aMapWithSize(6), hasValue("foo")));
+ assertThat(storageValues, allOf(aMapWithSize(10), hasValue(1)));
+ assertThat(storageValues, allOf(aMapWithSize(10), hasValue("foo")));
// And
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=1\n"
@@ -244,11 +284,19 @@ public class LocalFileConfigurationStorageTest {
storageValues = readAllLatest();
// Then
- assertThat(storageValues, allOf(aMapWithSize(6), hasValue(-1)));
- assertThat(storageValues, allOf(aMapWithSize(6), hasValue("strVal1")));
+ assertThat(storageValues, allOf(aMapWithSize(10), hasValue(-1)));
+ assertThat(storageValues, allOf(aMapWithSize(10), hasValue("strVal1")));
// And
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=-1\n"
@@ -267,6 +315,9 @@ public class LocalFileConfigurationStorageTest {
// Given
var topConfiguration = (TopConfiguration) treeGenerator.instantiateCfg(TopConfiguration.KEY, changer);
+ changer.start();
+ assertThat(changer.onDefaultsPersisted(), willCompleteSuccessfully());
+
topConfiguration.namedList().change(b -> {
b.create("name1", x -> {
x.changeStrVal("strVal1");
@@ -282,6 +333,14 @@ public class LocalFileConfigurationStorageTest {
// And values are saved to file
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=-1\n"
@@ -304,10 +363,18 @@ public class LocalFileConfigurationStorageTest {
var storageValues = readAllLatest();
// Then
- assertThat(storageValues, allOf(aMapWithSize(6), Matchers.not(hasValue("strVal1"))));
+ assertThat(storageValues, allOf(aMapWithSize(10), Matchers.not(hasValue("strVal1"))));
// And entity removed from file
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=-2\n"
@@ -325,10 +392,18 @@ public class LocalFileConfigurationStorageTest {
storageValues = readAllLatest();
// Then
- assertThat(storageValues, allOf(aMapWithSize(1), hasValue((short) 3)));
+ assertThat(storageValues, allOf(aMapWithSize(5), hasValue((short) 3)));
// And entity removed from file
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " shortVal=3\n"
+ "}\n"
));
@@ -389,6 +464,9 @@ public class LocalFileConfigurationStorageTest {
assertThat(Files.exists(getConfigFile()), is(false));
// When update configuration
+ changer.start();
+ assertThat(changer.onDefaultsPersisted(), willCompleteSuccessfully());
+
var topConfiguration = (TopConfiguration) treeGenerator.instantiateCfg(TopConfiguration.KEY, changer);
topConfiguration.namedList().change(b -> b.create("name1", x -> {
x.changeStrVal("strVal1");
@@ -398,6 +476,14 @@ public class LocalFileConfigurationStorageTest {
// Then file is created
assertThat(configFileContent(), equalToCompressingWhiteSpace(
"top {\n"
+ + " inner {\n"
+ + " boolVal=false\n"
+ + " someConfigurationValue {\n"
+ + " intVal=1\n"
+ + " strVal=foo\n"
+ + " }\n"
+ + " strVal=foo\n"
+ + " }\n"
+ " namedList=[\n"
+ " {\n"
+ " intVal=-1\n"
@@ -405,6 +491,7 @@ public class LocalFileConfigurationStorageTest {
+ " strVal=strVal1\n"
+ " }\n"
+ " ]\n"
+ + " shortVal=1\n"
+ "}\n"
));
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerExceptionHandlingTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerExceptionHandlingTest.java
index f3e846119e..0c42f9fe49 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerExceptionHandlingTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerExceptionHandlingTest.java
@@ -18,6 +18,8 @@
package org.apache.ignite.internal.sql.engine.exec.ddl;
import static org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
+import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
@@ -100,7 +102,7 @@ public class DdlCommandHandlerExceptionHandlingTest extends IgniteAbstractTest {
void before() {
registry.start();
- registry.initializeDefaults();
+ assertThat(registry.onDefaultsPersisted(), willCompleteSuccessfully());
DistributionZonesConfiguration zonesConfiguration = registry.getConfiguration(DistributionZonesConfiguration.KEY);