This is an automated email from the ASF dual-hosted git repository.

zhaojinchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 1306a78e510 Refactor pattern for metadata node (#26578)
1306a78e510 is described below

commit 1306a78e510d9a5371db9578753608e50be26305
Author: ChenJiaHao <[email protected]>
AuthorDate: Mon Jun 26 16:25:53 2023 +0800

    Refactor pattern for metadata node (#26578)
    
    * Refactor pattern for metadata node
    
    * Fix single node converter
---
 ...patibleEncryptRuleConfigurationSwapperTest.java |  4 +-
 ...NewYamlEncryptRuleConfigurationSwapperTest.java |  4 +-
 .../NewYamlMaskRuleConfigurationSwapperTest.java   |  4 +-
 ...writeSplittingRuleConfigurationSwapperTest.java |  2 +-
 .../event/ShadowRuleConfigurationEventBuilder.java | 12 ++++
 .../AlterDefaultShadowAlgorithmNameEvent.java      | 36 +++++++++++
 .../DeleteDefaultShadowAlgorithmNameEvent.java     | 32 ++++++++++
 .../metadata/converter/ShadowNodeConverter.java    | 18 +++++-
 .../DefaultShadowAlgorithmNameSubscriber.java      | 69 ++++++++++++++++++++++
 ...shardingsphere.infra.rule.RuleChangedSubscriber |  1 +
 .../NewYamlShadowRuleConfigurationSwapperTest.java |  8 +--
 .../metadata/converter/ShardingNodeConverter.java  | 14 +++--
 ...ewYamlShardingRuleConfigurationSwapperTest.java | 30 +++++-----
 .../config/converter/GlobalNodeConverter.java      |  6 +-
 .../metadata/converter/RuleItemNodeConverter.java  |  4 +-
 .../converter/RuleItemNodeConverterTest.java       |  4 +-
 16 files changed, 208 insertions(+), 40 deletions(-)

diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapperTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapperTest.java
index ed33f83f3c0..2b0917ebceb 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapperTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapperTest.java
@@ -73,13 +73,13 @@ class NewYamlCompatibleEncryptRuleConfigurationSwapperTest {
     @Test
     void assertSwapToObject() {
         Collection<YamlDataNode> config = new LinkedList<>();
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/compatible_encrypt/tables/foo", 
"columns:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/compatible_encrypt/tables/foo/versions/0", 
"columns:\n"
                 + "  foo_column:\n"
                 + "    cipherColumn: FIXTURE\n"
                 + "    encryptorName: FOO\n"
                 + "    logicColumn: foo_column\n"
                 + "name: foo\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/compatible_encrypt/encryptors/FOO", "type: 
FOO\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/compatible_encrypt/encryptors/FOO/versions/0",
 "type: FOO\n"));
         CompatibleEncryptRuleConfiguration result = 
swapper.swapToObject(config);
         assertThat(result.getTables().size(), is(1));
         assertThat(result.getTables().iterator().next().getName(), is("foo"));
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapperTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapperTest.java
index e26950640fb..bf0753bede6 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapperTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapperTest.java
@@ -72,14 +72,14 @@ class NewYamlEncryptRuleConfigurationSwapperTest {
     @Test
     void assertSwapToObject() {
         Collection<YamlDataNode> config = new LinkedList<>();
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/encrypt/tables/foo", "columns:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/encrypt/tables/foo/versions/0", 
"columns:\n"
                 + "  foo_column:\n"
                 + "    cipher:\n"
                 + "      encryptorName: FOO\n"
                 + "      name: FIXTURE\n"
                 + "    name: foo_column\n"
                 + "name: foo\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/encrypt/encryptors/FOO", "type: FOO\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/encrypt/encryptors/FOO/versions/0", "type: 
FOO\n"));
         EncryptRuleConfiguration result = swapper.swapToObject(config);
         assertThat(result.getTables().size(), is(1));
         assertThat(result.getTables().iterator().next().getName(), is("foo"));
diff --git 
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapperTest.java
 
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapperTest.java
index d7ce591b38b..ac754f7de83 100644
--- 
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapperTest.java
+++ 
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapperTest.java
@@ -71,12 +71,12 @@ class NewYamlMaskRuleConfigurationSwapperTest {
     @Test
     void assertSwapToObject() {
         Collection<YamlDataNode> config = new LinkedList<>();
-        config.add(new YamlDataNode("/metadata/foo_db/rules/mask/tables/foo", 
"columns:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/mask/tables/foo/versions/0", "columns:\n"
                 + "  foo_column:\n"
                 + "    logicColumn: foo_column\n"
                 + "    maskAlgorithm: FIXTURE\n"
                 + "name: foo\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/mask/algorithms/FIXTURE", "type: 
FIXTURE\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/mask/algorithms/FIXTURE/versions/0", 
"type: FIXTURE\n"));
         MaskRuleConfiguration result = swapper.swapToObject(config);
         assertThat(result.getTables().size(), is(1));
         assertThat(result.getTables().iterator().next().getName(), is("foo"));
diff --git 
a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapperTest.java
 
b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapperTest.java
index 843406b7889..21c5b690d1f 100644
--- 
a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapperTest.java
+++ 
b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapperTest.java
@@ -69,7 +69,7 @@ class NewYamlReadwriteSplittingRuleConfigurationSwapperTest {
     @Test
     void assertSwapToObject() {
         Collection<YamlDataNode> config = new LinkedList<>();
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/readwrite_splitting/data_sources/group_0/version/0",
 "loadBalancerName: random\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/readwrite_splitting/data_sources/group_0/versions/0",
 "loadBalancerName: random\n"
                 + "readDataSourceNames:\n"
                 + "- read_ds_0\n"
                 + "- read_ds_1\n"
diff --git 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
index a8b20cfe88d..544fb0a19b0 100644
--- 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
+++ 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
@@ -22,7 +22,9 @@ import 
org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
 import org.apache.shardingsphere.mode.spi.RuleConfigurationEventBuilder;
+import 
org.apache.shardingsphere.shadow.event.algorithm.AlterDefaultShadowAlgorithmNameEvent;
 import 
org.apache.shardingsphere.shadow.event.algorithm.AlterShadowAlgorithmEvent;
+import 
org.apache.shardingsphere.shadow.event.algorithm.DeleteDefaultShadowAlgorithmNameEvent;
 import 
org.apache.shardingsphere.shadow.event.algorithm.DeleteShadowAlgorithmEvent;
 import 
org.apache.shardingsphere.shadow.event.datasource.AddShadowDataSourceEvent;
 import 
org.apache.shardingsphere.shadow.event.datasource.AlterShadowDataSourceEvent;
@@ -56,6 +58,9 @@ public final class ShadowRuleConfigurationEventBuilder 
implements RuleConfigurat
         if (algorithmName.isPresent() && 
!Strings.isNullOrEmpty(event.getValue())) {
             return createShadowAlgorithmEvent(databaseName, 
algorithmName.get(), event);
         }
+        if 
(ShadowNodeConverter.isDefaultAlgorithmNameWithActiveVersionPath(event.getKey())
 && !Strings.isNullOrEmpty(event.getValue())) {
+            return createDefaultShadowAlgorithmNameEvent(databaseName, event);
+        }
         return Optional.empty();
     }
     
@@ -85,4 +90,11 @@ public final class ShadowRuleConfigurationEventBuilder 
implements RuleConfigurat
         }
         return Optional.of(new DeleteShadowAlgorithmEvent(databaseName, 
algorithmName));
     }
+    
+    private Optional<GovernanceEvent> 
createDefaultShadowAlgorithmNameEvent(final String databaseName, final 
DataChangedEvent event) {
+        if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
+            return Optional.of(new 
AlterDefaultShadowAlgorithmNameEvent(databaseName, event.getKey(), 
event.getValue()));
+        }
+        return Optional.of(new 
DeleteDefaultShadowAlgorithmNameEvent(databaseName));
+    }
 }
diff --git 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterDefaultShadowAlgorithmNameEvent.java
 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterDefaultShadowAlgorithmNameEvent.java
new file mode 100644
index 00000000000..3b17bf7caf8
--- /dev/null
+++ 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterDefaultShadowAlgorithmNameEvent.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.shadow.event.algorithm;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
+
+/**
+ * Alter default shadow algorithm name event.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class AlterDefaultShadowAlgorithmNameEvent implements 
GovernanceEvent {
+    
+    private final String databaseName;
+    
+    private final String activeVersionKey;
+    
+    private final String activeVersion;
+}
diff --git 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteDefaultShadowAlgorithmNameEvent.java
 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteDefaultShadowAlgorithmNameEvent.java
new file mode 100644
index 00000000000..1c6b12e532d
--- /dev/null
+++ 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteDefaultShadowAlgorithmNameEvent.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.shadow.event.algorithm;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
+
+/**
+ * Delete default shadow algorithm name event.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class DeleteDefaultShadowAlgorithmNameEvent implements 
GovernanceEvent {
+    
+    private final String databaseName;
+}
diff --git 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
index b62d7b20f7d..57edaf75740 100644
--- 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
+++ 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
@@ -33,6 +33,10 @@ public final class ShadowNodeConverter {
     
     private static final String DEFAULT_ALGORITHM_NAME = 
"default_algorithm_name";
     
+    private static final String VERSIONS = "/versions/\\d+$";
+    
+    private static final String ACTIVE_VERSION = "/active_version$";
+    
     private static final RuleRootNodeConverter ROOT_NODE_CONVERTER = new 
RuleRootNodeConverter("shadow");
     
     private static final RuleItemNodeConverter DATA_SOURCE_NODE_CONVERTER = 
new RuleItemNodeConverter(ROOT_NODE_CONVERTER, "data_sources");
@@ -93,7 +97,19 @@ public final class ShadowNodeConverter {
      * @return true or false
      */
     public static boolean isDefaultAlgorithmNamePath(final String rulePath) {
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_ALGORITHM_NAME + "$", Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_ALGORITHM_NAME + VERSIONS, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find();
+    }
+    
+    /**
+     * Is default algorithm name with active version path.
+     *
+     * @param rulePath rule path
+     * @return true or false
+     */
+    public static boolean isDefaultAlgorithmNameWithActiveVersionPath(final 
String rulePath) {
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_ALGORITHM_NAME + ACTIVE_VERSION, Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
diff --git 
a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/DefaultShadowAlgorithmNameSubscriber.java
 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/DefaultShadowAlgorithmNameSubscriber.java
new file mode 100644
index 00000000000..9fa1b8c6f44
--- /dev/null
+++ 
b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/DefaultShadowAlgorithmNameSubscriber.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.shadow.subscriber;
+
+import com.google.common.eventbus.Subscribe;
+import lombok.Setter;
+import org.apache.shardingsphere.infra.instance.InstanceContext;
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.rule.RuleChangedSubscriber;
+import 
org.apache.shardingsphere.mode.event.config.DatabaseRuleConfigurationChangedEvent;
+import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.event.algorithm.AlterDefaultShadowAlgorithmNameEvent;
+import 
org.apache.shardingsphere.shadow.event.algorithm.DeleteDefaultShadowAlgorithmNameEvent;
+import org.apache.shardingsphere.shadow.rule.ShadowRule;
+
+import java.util.Map;
+
+/**
+ * Default shadow algorithm name subscriber.
+ */
+@SuppressWarnings("UnstableApiUsage")
+@Setter
+public final class DefaultShadowAlgorithmNameSubscriber implements 
RuleChangedSubscriber {
+    
+    private Map<String, ShardingSphereDatabase> databases;
+    
+    private InstanceContext instanceContext;
+    
+    /**
+     * Renew with alter default algorithm name.
+     *
+     * @param event alter default algorithm name event
+     */
+    @Subscribe
+    public synchronized void renew(final AlterDefaultShadowAlgorithmNameEvent 
event) {
+        ShardingSphereDatabase database = 
databases.get(event.getDatabaseName());
+        ShadowRuleConfiguration config = (ShadowRuleConfiguration) 
database.getRuleMetaData().getSingleRule(ShadowRule.class).getConfiguration();
+        
config.setDefaultShadowAlgorithmName(instanceContext.getModeContextManager().getVersionPathByActiveVersionKey(event.getActiveVersionKey(),
 event.getActiveVersion()));
+        instanceContext.getEventBusContext().post(new 
DatabaseRuleConfigurationChangedEvent(event.getDatabaseName(), config));
+    }
+    
+    /**
+     * Renew with delete default algorithm name.
+     *
+     * @param event delete default algorithm name event
+     */
+    @Subscribe
+    public synchronized void renew(final DeleteDefaultShadowAlgorithmNameEvent 
event) {
+        ShardingSphereDatabase database = 
databases.get(event.getDatabaseName());
+        ShadowRuleConfiguration config = (ShadowRuleConfiguration) 
database.getRuleMetaData().getSingleRule(ShadowRule.class).getConfiguration();
+        config.setDefaultShadowAlgorithmName(null);
+        instanceContext.getEventBusContext().post(new 
DatabaseRuleConfigurationChangedEvent(event.getDatabaseName(), config));
+    }
+}
diff --git 
a/features/shadow/core/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.rule.RuleChangedSubscriber
 
b/features/shadow/core/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.rule.RuleChangedSubscriber
index b78e6e0b888..30728589b7e 100644
--- 
a/features/shadow/core/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.rule.RuleChangedSubscriber
+++ 
b/features/shadow/core/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.rule.RuleChangedSubscriber
@@ -18,3 +18,4 @@
 org.apache.shardingsphere.shadow.subscriber.ShadowDataSourceSubscriber
 org.apache.shardingsphere.shadow.subscriber.ShadowTableSubscriber
 org.apache.shardingsphere.shadow.subscriber.ShadowAlgorithmSubscriber
+org.apache.shardingsphere.shadow.subscriber.DefaultShadowAlgorithmNameSubscriber
diff --git 
a/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapperTest.java
 
b/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapperTest.java
index eb3ff2249bc..2ce4f375886 100644
--- 
a/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapperTest.java
+++ 
b/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapperTest.java
@@ -84,14 +84,14 @@ class NewYamlShadowRuleConfigurationSwapperTest {
     @Test
     void assertSwapToObject() {
         Collection<YamlDataNode> config = new LinkedList<>();
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/data_sources/foo_db", 
"productionDataSourceName: ds_0\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/data_sources/foo_db/versions/0", 
"productionDataSourceName: ds_0\n"
                 + "shadowDataSourceName: ds_1\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/tables/foo_table", 
"dataSourceNames:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/tables/foo_table/versions/0", 
"dataSourceNames:\n"
                 + "- ds_0\n"
                 + "shadowAlgorithmNames:\n"
                 + "- FIXTURE\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/algorithms/FIXTURE", "type: 
FIXTURE\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/default_algorithm_name", 
"FIXTURE"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/algorithms/FIXTURE/versions/0", 
"type: FIXTURE\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/shadow/default_algorithm_name/versions/0", 
"FIXTURE"));
         ShadowRuleConfiguration result = swapper.swapToObject(config);
         assertThat(result.getDataSources().size(), is(1));
         assertThat(result.getDataSources().iterator().next().getName(), 
is("foo_db"));
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
index 26d7132d6e0..f4a6acbabaa 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
@@ -45,6 +45,8 @@ public final class ShardingNodeConverter {
     
     private static final String SHARDING_CACHE_NODE = "sharding_cache";
     
+    private static final String VERSIONS = "/versions/\\d+$";
+    
     private static final String ACTIVE_VERSION = "/active_version$";
     
     private static final RuleRootNodeConverter ROOT_NODE_CONVERTER = new 
RuleRootNodeConverter("sharding");
@@ -185,7 +187,7 @@ public final class ShardingNodeConverter {
      * @return true or false
      */
     public static boolean isDefaultDatabaseStrategyPath(final String rulePath) 
{
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_DATABASE_STRATEGY_NODE + "$", 
Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_DATABASE_STRATEGY_NODE + VERSIONS, 
Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
@@ -197,7 +199,7 @@ public final class ShardingNodeConverter {
      * @return true or false
      */
     public static boolean isDefaultTableStrategyPath(final String rulePath) {
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_TABLE_STRATEGY_NODE + "$", 
Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_TABLE_STRATEGY_NODE + VERSIONS, 
Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
@@ -209,7 +211,7 @@ public final class ShardingNodeConverter {
      * @return true or false
      */
     public static boolean isDefaultKeyGenerateStrategyPath(final String 
rulePath) {
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_KEY_GENERATE_STRATEGY_NODE + "$", 
Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_KEY_GENERATE_STRATEGY_NODE + VERSIONS, 
Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
@@ -221,7 +223,7 @@ public final class ShardingNodeConverter {
      * @return true or false
      */
     public static boolean isDefaultAuditStrategyPath(final String rulePath) {
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_AUDIT_STRATEGY_NODE + "$", 
Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_AUDIT_STRATEGY_NODE + VERSIONS, 
Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
@@ -233,7 +235,7 @@ public final class ShardingNodeConverter {
      * @return true or false
      */
     public static boolean isDefaultShardingColumnPath(final String rulePath) {
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_SHARDING_COLUMN_NODE + "$", 
Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_SHARDING_COLUMN_NODE + VERSIONS, 
Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
@@ -245,7 +247,7 @@ public final class ShardingNodeConverter {
      * @return true or false
      */
     public static boolean isShardingCachePath(final String rulePath) {
-        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
SHARDING_CACHE_NODE + "$", Pattern.CASE_INSENSITIVE);
+        Pattern pattern = 
Pattern.compile(ROOT_NODE_CONVERTER.getRuleNodePrefix() + "/" + 
SHARDING_CACHE_NODE + VERSIONS, Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapperTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapperTest.java
index bb54a89cd6d..1f0a48f7954 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapperTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapperTest.java
@@ -132,7 +132,7 @@ class NewYamlShardingRuleConfigurationSwapperTest {
     @Test
     void assertSwapToObject() {
         Collection<YamlDataNode> config = new LinkedList<>();
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/tables/LOGIC_TABLE", 
"actualDataNodes: ds_${0..1}.table_${0..2}\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/tables/LOGIC_TABLE/versions/0", 
"actualDataNodes: ds_${0..1}.table_${0..2}\n"
                 + "auditStrategy:\n"
                 + "  allowHintDisable: false\n"
                 + "  auditorNames:\n"
@@ -149,7 +149,7 @@ class NewYamlShardingRuleConfigurationSwapperTest {
                 + "  standard:\n"
                 + "    shardingAlgorithmName: table_inline\n"
                 + "    shardingColumn: order_id\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/tables/SUB_LOGIC_TABLE", 
"actualDataNodes: ds_${0..1}.sub_table_${0..2}\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/tables/SUB_LOGIC_TABLE/versions/0",
 "actualDataNodes: ds_${0..1}.sub_table_${0..2}\n"
                 + "databaseStrategy:\n"
                 + "  standard:\n"
                 + "    shardingAlgorithmName: database_inline\n"
@@ -162,7 +162,7 @@ class NewYamlShardingRuleConfigurationSwapperTest {
                 + "  standard:\n"
                 + "    shardingAlgorithmName: table_inline\n"
                 + "    shardingColumn: order_id\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/auto_tables/auto_table", 
"actualDataSources: ds_1,ds_2\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/auto_tables/auto_table/versions/0",
 "actualDataSources: ds_1,ds_2\n"
                 + "auditStrategy:\n"
                 + "  allowHintDisable: true\n"
                 + "  auditorNames:\n"
@@ -175,27 +175,27 @@ class NewYamlShardingRuleConfigurationSwapperTest {
                 + "  standard:\n"
                 + "    shardingAlgorithmName: hash_mod\n"
                 + "    shardingColumn: user_id\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/binding_tables/foo", 
"foo:LOGIC_TABLE,SUB_LOGIC_TABLE"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_database_strategy",
 "standard:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/binding_tables/foo/versions/0", 
"foo:LOGIC_TABLE,SUB_LOGIC_TABLE"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_database_strategy/versions/0",
 "standard:\n"
                 + "  shardingAlgorithmName: standard\n"
                 + "  shardingColumn: ds_id\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_table_strategy",
 "standard:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_table_strategy/versions/0",
 "standard:\n"
                 + "  shardingAlgorithmName: standard\n"
                 + "  shardingColumn: table_id\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_key_generate_strategy",
 "column: id\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_key_generate_strategy/versions/0",
 "column: id\n"
                 + "keyGeneratorName: default\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_audit_strategy",
 "allowHintDisable: false\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_audit_strategy/versions/0",
 "allowHintDisable: false\n"
                 + "auditorNames:\n"
                 + "- audit_algorithm\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/algorithms/core_standard_fixture",
 "type: CORE.STANDARD.FIXTURE\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/algorithms/hash_mod", "props:\n"
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/algorithms/core_standard_fixture/versions/0",
 "type: CORE.STANDARD.FIXTURE\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/algorithms/hash_mod/versions/0", 
"props:\n"
                 + "  sharding-count: '4'\n"
                 + "type: hash_mod\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/key_generators/uuid", "type: 
UUID\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/key_generators/default", "type: 
UUID\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/key_generators/auto_increment", 
"type: AUTO_INCREMENT.FIXTURE\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/auditors/audit_algorithm", "type: 
DML_SHARDING_CONDITIONS\n"));
-        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_sharding_column",
 "table_id"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/key_generators/uuid/versions/0", 
"type: UUID\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/key_generators/default/versions/0",
 "type: UUID\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/key_generators/auto_increment/versions/0",
 "type: AUTO_INCREMENT.FIXTURE\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/auditors/audit_algorithm/versions/0",
 "type: DML_SHARDING_CONDITIONS\n"));
+        config.add(new 
YamlDataNode("/metadata/foo_db/rules/sharding/default_strategies/default_sharding_column/versions/0",
 "table_id"));
         ShardingRuleConfiguration result = swapper.swapToObject(config);
         assertThat(result.getTables().size(), is(2));
         assertThat(result.getTables().iterator().next().getLogicTable(), 
is("LOGIC_TABLE"));
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/converter/GlobalNodeConverter.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/converter/GlobalNodeConverter.java
index 95df3b176d6..3a36d27527f 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/converter/GlobalNodeConverter.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/converter/GlobalNodeConverter.java
@@ -44,7 +44,7 @@ public final class GlobalNodeConverter {
      * @return version
      */
     public static Optional<String> getVersion(final String ruleName, final 
String rulePath) {
-        Pattern pattern = Pattern.compile(getVersionsNode(ruleName) + 
"/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Pattern pattern = Pattern.compile(getVersionsNode(ruleName) + 
"/(\\d+)$", Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find() ? Optional.of(matcher.group(1)) : 
Optional.empty();
     }
@@ -60,7 +60,7 @@ public final class GlobalNodeConverter {
      * @return true or false
      */
     public static boolean isRuleActiveVersionPath(final String rulePath) {
-        Pattern pattern = Pattern.compile(getRuleNameNode() + 
"/([\\w\\-]+)/active_version$", Pattern.CASE_INSENSITIVE);
+        Pattern pattern = Pattern.compile(getRuleNameNode() + 
"/(\\w+)/active_version$", Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find();
     }
@@ -88,7 +88,7 @@ public final class GlobalNodeConverter {
      * @return rule name
      */
     public static Optional<String> getRuleName(final String rulePath) {
-        Pattern pattern = Pattern.compile(getRuleNameNode() + 
"/([\\w\\-]+)/active_version$", Pattern.CASE_INSENSITIVE);
+        Pattern pattern = Pattern.compile(getRuleNameNode() + 
"/(\\w+)/active_version$", Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find() ? Optional.of(matcher.group(1)) : 
Optional.empty();
     }
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverter.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverter.java
index 5220e5c5d13..4fc82301894 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverter.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverter.java
@@ -26,9 +26,9 @@ import java.util.regex.Pattern;
  */
 public final class RuleItemNodeConverter {
     
-    private static final String RULE_NAME = "/([\\w\\-]+)?";
+    private static final String RULE_NAME = "/(\\w+)/versions/\\d+$";
     
-    private static final String RULE_ACTIVE_VERSION = 
"/([\\w\\-]+)/active_version$";
+    private static final String RULE_ACTIVE_VERSION = 
"/(\\w+)/active_version$";
     
     private final String itemsNode;
     
diff --git 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverterTest.java
 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverterTest.java
index 50caf0455d8..45d6b806291 100644
--- 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverterTest.java
+++ 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/converter/RuleItemNodeConverterTest.java
@@ -36,12 +36,12 @@ class RuleItemNodeConverterTest {
     
     @Test
     void assertIsPath() {
-        
assertTrue(converter.isPath("/metadata/foo_db/rules/foo/tables/foo_table"));
+        
assertTrue(converter.isPath("/metadata/foo_db/rules/foo/tables/foo_table/versions/0"));
     }
     
     @Test
     void assertGetName() {
-        Optional<String> actual = 
converter.getName("/metadata/foo_db/rules/foo/tables/foo_table");
+        Optional<String> actual = 
converter.getName("/metadata/foo_db/rules/foo/tables/foo_table/versions/0");
         assertTrue(actual.isPresent());
         assertThat(actual.get(), is("foo_table"));
     }


Reply via email to