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 <[email protected]> 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
