You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2025/07/16 15:25:16 UTC
(ignite-3) 01/01: Support named lists
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch ignite-25571
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 9fe314c833181113699f18b1326e0a6017ef5ac0
Author: amashenkov <am...@apache.org>
AuthorDate: Wed Jul 16 18:25:02 2025 +0300
Support named lists
---
.../ConfigurationCompatibilityTest.java | 2 +-
.../compatibility/framework/ConfigNode.java | 20 +++++-
.../framework/ConfigurationTreeComparator.java | 38 +++++-----
.../ConfigurationTreeComparatorSelfTest.java | 77 +++++++++------------
.../framework/ConfigurationTreeScanner.java | 7 +-
.../compatibility/configuration/snapshot.bin | Bin 4020 -> 4039 bytes
6 files changed, 78 insertions(+), 66 deletions(-)
diff --git a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/ConfigurationCompatibilityTest.java b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/ConfigurationCompatibilityTest.java
index 73765825665..61c343a442a 100644
--- a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/ConfigurationCompatibilityTest.java
+++ b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/ConfigurationCompatibilityTest.java
@@ -114,7 +114,7 @@ public class ConfigurationCompatibilityTest extends IgniteAbstractTest {
Set<ConfigurationModule> allModules = allModules();
List<ConfigNode> snapshotMetadata = loadSnapshotFromResource(SNAPSHOTS_RESOURCE_LOCATION + fileName);
- ComparisonContext ctx = new ComparisonContext(allModules);
+ ComparisonContext ctx = ComparisonContext.create(allModules);
ConfigurationTreeComparator.ensureCompatible(snapshotMetadata, currentMetadata, ctx);
}
diff --git a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigNode.java b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigNode.java
index b964f9cedbd..0293a69fc81 100644
--- a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigNode.java
+++ b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigNode.java
@@ -200,6 +200,22 @@ public class ConfigNode {
return flags.contains(Flags.IS_VALUE);
}
+ /**
+ * Returns {@code true} if this node represents a named list node, {@code false} otherwise.
+ */
+ @JsonIgnore
+ public boolean isNamedNode() {
+ return flags.contains(Flags.IS_NAMED_NODE);
+ }
+
+ /**
+ * Returns {@code true} if this node represents an inner config node, {@code false} otherwise.
+ */
+ @JsonIgnore
+ public boolean isInnerNode() {
+ return flags.contains(Flags.IS_INNER_NODE);
+ }
+
/**
* Returns {@code true} if this node represents internal part of configuration, {@code false} otherwise.
*/
@@ -294,7 +310,9 @@ public class ConfigNode {
IS_ROOT(1),
IS_VALUE(1 << 1),
IS_DEPRECATED(1 << 2),
- IS_INTERNAL(1 << 3);
+ IS_INTERNAL(1 << 3),
+ IS_NAMED_NODE(1 << 4),
+ IS_INNER_NODE(1 << 5);
private final int mask;
diff --git a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparator.java b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparator.java
index 73d4b4b9b41..fd5d6a4d143 100644
--- a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparator.java
+++ b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparator.java
@@ -75,6 +75,8 @@ public class ConfigurationTreeComparator {
@Override
public void visit(ConfigNode node) {
+ assert node.isRoot() || node.isInnerNode() || node.isNamedNode() || node.isValue();
+
if (node.isValue() && !compContext.shouldIgnore(node.path())) {
validator.accept(node);
}
@@ -147,8 +149,8 @@ public class ConfigurationTreeComparator {
*/
private static boolean match(ConfigNode node, ConfigNode candidate) {
return Objects.equals(candidate.kind(), node.kind())
- && matchNames(candidate, node)
&& validateFlags(candidate, node)
+ && matchNames(candidate, node)
&& candidate.deletedPrefixes().containsAll(node.deletedPrefixes())
&& (!node.isValue() || Objects.equals(candidate.type(), node.type())); // Value node types can be changed.
}
@@ -177,7 +179,7 @@ public class ConfigurationTreeComparator {
private static boolean matchNames(ConfigNode candidate, ConfigNode node) {
return Objects.equals(candidate.name(), node.name())
- || (node.isValue() && candidate.isValue() && compareUsingLegacyNames(candidate, node));
+ || compareUsingLegacyNames(candidate, node);
}
private static boolean compareUsingLegacyNames(ConfigNode candidate, ConfigNode node) {
@@ -187,6 +189,8 @@ public class ConfigurationTreeComparator {
private static boolean validateFlags(ConfigNode candidate, ConfigNode node) {
return node.isRoot() == candidate.isRoot()
&& node.isValue() == candidate.isValue()
+ && node.isNamedNode() == candidate.isNamedNode()
+ && node.isInnerNode() == candidate.isInnerNode()
&& (!candidate.isInternal() || node.isInternal()) // Public property\tree can't be hidden.
&& (!node.isDeprecated() || candidate.isDeprecated()); // Deprecation shouldn't be removed.
}
@@ -216,29 +220,27 @@ public class ConfigurationTreeComparator {
/** Holder class for comparison context. */
public static class ComparisonContext {
- private final Set<ConfigurationModule> configurationModules;
- private Collection<KeyIgnorer> deletedItems;
+ public static ComparisonContext create(Set<ConfigurationModule> configurationModules) {
+ Set<String> prefixes = configurationModules.stream()
+ .map(ConfigurationModule::deletedPrefixes)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toSet());
- ComparisonContext() {
- this.configurationModules = Set.of();
+ return create(prefixes);
}
- public ComparisonContext(Set<ConfigurationModule> configurationModules) {
- this.configurationModules = configurationModules;
+ public static ComparisonContext create(Collection<String> prefixes) {
+ return new ComparisonContext(KeyIgnorer.fromDeletedPrefixes(prefixes));
}
- boolean shouldIgnore(String path) {
- if (deletedItems == null) {
- deletedItems = new ArrayList<>(configurationModules.size());
-
- for (ConfigurationModule module : configurationModules) {
- KeyIgnorer keyIgnorer = KeyIgnorer.fromDeletedPrefixes(module.deletedPrefixes());
+ private final KeyIgnorer deletedItems;
- deletedItems.add(keyIgnorer);
- }
- }
+ ComparisonContext(KeyIgnorer deletedItems) {
+ this.deletedItems = deletedItems;
+ }
- return deletedItems.stream().anyMatch(i -> i.shouldIgnore(path));
+ boolean shouldIgnore(String path) {
+ return deletedItems.shouldIgnore(path);
}
}
}
diff --git a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparatorSelfTest.java b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparatorSelfTest.java
index ab6e421e470..d4b1e28e449 100644
--- a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparatorSelfTest.java
+++ b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeComparatorSelfTest.java
@@ -94,7 +94,7 @@ public class ConfigurationTreeComparatorSelfTest {
));
ConfigNode root2 = createRoot("root1");
- ConfigNode child = new ConfigNode(root2, Map.of(Attributes.NAME, "child"), List.of(), EnumSet.noneOf(Flags.class));
+ ConfigNode child = new ConfigNode(root2, Map.of(Attributes.NAME, "child"), List.of(), EnumSet.of(Flags.IS_INNER_NODE));
root2.addChildNodes(List.of(child));
child.addChildNodes(
new ConfigNode(child, Map.of(Attributes.NAME, "child"), List.of(), EnumSet.of(Flags.IS_VALUE))
@@ -105,6 +105,26 @@ public class ConfigurationTreeComparatorSelfTest {
assertIncompatible(root2, root1);
}
+ @Test
+ void innerNodeTypeCantBeChanged() {
+ ConfigNode root1 = createRoot("root1");
+ ConfigNode root2 = createRoot("root1");
+
+ ConfigNode inner1 = new ConfigNode(root1, Map.of(Attributes.NAME, "inner"), List.of(), EnumSet.of(Flags.IS_NAMED_NODE));
+ ConfigNode inner2 = new ConfigNode(root2, Map.of(Attributes.NAME, "inner"), List.of(), EnumSet.of(Flags.IS_INNER_NODE));
+
+ ConfigNode leafNode1 = new ConfigNode(inner1, Map.of(Attributes.NAME, "child"), List.of(), EnumSet.of(Flags.IS_VALUE));
+ ConfigNode leafNode2 = new ConfigNode(inner2, Map.of(Attributes.NAME, "child"), List.of(), EnumSet.of(Flags.IS_VALUE));
+
+ root1.addChildNodes(inner1);
+ root2.addChildNodes(inner2);
+ inner1.addChildNodes(leafNode1);
+ inner2.addChildNodes(leafNode2);
+
+ assertIncompatible(root1, root2);
+ assertIncompatible(root2, root1);
+ }
+
@Test
void propertyCantBeRemoved() {
ConfigNode root1 = createRoot("root1");
@@ -218,7 +238,7 @@ public class ConfigurationTreeComparatorSelfTest {
Set<ConfigurationModule> allModules = Set.of(configModule);
- assertCompatible(snapshotMetadata, currentMetadata, new ComparisonContext(allModules));
+ assertCompatible(snapshotMetadata, currentMetadata, ComparisonContext.create(allModules));
// missed deleted properties
configModule = new ConfigurationModule() {
@@ -235,7 +255,7 @@ public class ConfigurationTreeComparatorSelfTest {
allModules = Set.of(configModule);
- assertIncompatible(snapshotMetadata, currentMetadata, new ComparisonContext(allModules));
+ assertIncompatible(snapshotMetadata, currentMetadata, ComparisonContext.create(allModules));
}
/**
@@ -248,7 +268,7 @@ public class ConfigurationTreeComparatorSelfTest {
EnumSet.of(Flags.IS_ROOT));
ConfigNode compoundProp = new ConfigNode(root, Map.of(Attributes.NAME, "list"), List.of(),
- EnumSet.of(Flags.IS_INTERNAL));
+ EnumSet.of(Flags.IS_INNER_NODE));
ConfigNode firstMemberOfCompoundProp = new ConfigNode(compoundProp, Map.of(Attributes.NAME, "firstProperty"), List.of(),
EnumSet.of(Flags.IS_VALUE));
@@ -266,44 +286,15 @@ public class ConfigurationTreeComparatorSelfTest {
EnumSet.of(Flags.IS_ROOT));
compoundProp = new ConfigNode(root, Map.of(Attributes.NAME, "list"), List.of(),
- EnumSet.of(Flags.IS_INTERNAL));
+ EnumSet.of(Flags.IS_INNER_NODE));
root.addChildNodes(List.of(compoundProp));
List<ConfigNode> currentMetadata = List.of(root);
- ConfigurationModule configModule = new ConfigurationModule() {
- @Override
- public ConfigurationType type() {
- return ConfigurationType.LOCAL;
- }
-
- @Override
- public Collection<String> deletedPrefixes() {
- return List.of("root.list.*");
- }
- };
-
- Set<ConfigurationModule> allModules = Set.of(configModule);
-
- assertCompatible(snapshotMetadata, currentMetadata, new ComparisonContext(allModules));
-
+ assertCompatible(snapshotMetadata, currentMetadata, ComparisonContext.create(List.of("root.list.*")));
// missed deleted properties
- configModule = new ConfigurationModule() {
- @Override
- public ConfigurationType type() {
- return ConfigurationType.LOCAL;
- }
-
- @Override
- public Collection<String> deletedPrefixes() {
- return List.of("root.list_notExist.*");
- }
- };
-
- allModules = Set.of(configModule);
-
- assertIncompatible(snapshotMetadata, currentMetadata, new ComparisonContext(allModules));
+ assertIncompatible(snapshotMetadata, currentMetadata, ComparisonContext.create(List.of("root.list_notExist.*")));
}
@Test
@@ -406,10 +397,8 @@ public class ConfigurationTreeComparatorSelfTest {
}
/**
- * Test scenario. <br>
- * config ver1 has property : prop1 <br>
- * config ver2 has renamed property : prop1 -> prop2 <br>
- * config ver3 has deleted property : prop1, prop2 <br>
+ * Test scenario. <br> config ver1 has property : prop1 <br> config ver2 has renamed property : prop1 -> prop2 <br> config ver3 has
+ * deleted property : prop1, prop2 <br>
* <br>
* Check config transitions are possible: ver1 -> ver2, ver1 -> ver3, ver2 -> ver3
*/
@@ -461,8 +450,8 @@ public class ConfigurationTreeComparatorSelfTest {
Set<ConfigurationModule> allModules = Set.of(configModule);
assertCompatible(metadataVer1, metadataVer2);
- assertCompatible(metadataVer1, metadataVer3, new ComparisonContext(allModules));
- assertCompatible(metadataVer2, metadataVer3, new ComparisonContext(allModules));
+ assertCompatible(metadataVer1, metadataVer3, ComparisonContext.create(allModules));
+ assertCompatible(metadataVer2, metadataVer3, ComparisonContext.create(allModules));
}
private static ConfigNode createRoot(String name) {
@@ -483,7 +472,7 @@ public class ConfigurationTreeComparatorSelfTest {
}
private static void assertCompatible(List<ConfigNode> oldConfig, List<ConfigNode> newConfig) {
- assertCompatible(oldConfig, newConfig, new ComparisonContext());
+ assertCompatible(oldConfig, newConfig, ComparisonContext.create(List.of()));
}
private static void assertCompatible(List<ConfigNode> oldConfig, List<ConfigNode> newConfig, ComparisonContext compContext) {
@@ -495,7 +484,7 @@ public class ConfigurationTreeComparatorSelfTest {
}
private static void assertIncompatible(List<ConfigNode> oldConfig, List<ConfigNode> newConfig) {
- assertIncompatible(oldConfig, newConfig, new ComparisonContext());
+ assertIncompatible(oldConfig, newConfig, ComparisonContext.create(List.of()));
}
private static void assertIncompatible(List<ConfigNode> oldConfig, List<ConfigNode> newConfig, ComparisonContext compContext) {
diff --git a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeScanner.java b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeScanner.java
index b5795826ffe..57994671dd3 100644
--- a/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeScanner.java
+++ b/modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeScanner.java
@@ -191,8 +191,11 @@ public class ConfigurationTreeScanner {
private static EnumSet<ConfigNode.Flags> extractFlags(Field field) {
EnumSet<ConfigNode.Flags> flags = EnumSet.noneOf(ConfigNode.Flags.class);
- if (!field.isAnnotationPresent(NamedConfigValue.class)
- && !field.isAnnotationPresent(ConfigValue.class)) {
+ if (field.isAnnotationPresent(NamedConfigValue.class)) {
+ flags.add(Flags.IS_NAMED_NODE);
+ } else if (field.isAnnotationPresent(ConfigValue.class)) {
+ flags.add(Flags.IS_INNER_NODE);
+ } else {
flags.add(Flags.IS_VALUE);
}
diff --git a/modules/runner/src/test/resources/compatibility/configuration/snapshot.bin b/modules/runner/src/test/resources/compatibility/configuration/snapshot.bin
index a0ed7892a13..6e100c42880 100644
Binary files a/modules/runner/src/test/resources/compatibility/configuration/snapshot.bin and b/modules/runner/src/test/resources/compatibility/configuration/snapshot.bin differ