You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zi...@apache.org on 2023/06/26 21:16:16 UTC

[shardingsphere] branch master updated: Add RuleNodePath to simplify rule node converters (#26597)

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

zichaowang 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 038b82e355d Add RuleNodePath to simplify rule node converters (#26597)
038b82e355d is described below

commit 038b82e355dc48070f3593f510dd9e1afd798cb4
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Tue Jun 27 05:16:09 2023 +0800

    Add RuleNodePath to simplify rule node converters (#26597)
    
    * Add RuleRootNodePath to simplify rule node converter
    
    * Add RuleRootNodePath to simplify rule node converter
    
    * Add RuleRootNodePath to simplify rule node converter
---
 .../BroadcastRuleConfigurationEventBuilder.java    |   7 +-
 .../metadata/converter/BroadcastNodeConverter.java |  39 ++---
 .../NewYamlBroadcastRuleConfigurationSwapper.java  |   7 +-
 ...atibleEncryptRuleConfigurationEventBuilder.java |   9 +-
 .../EncryptRuleConfigurationEventBuilder.java      |   9 +-
 .../converter/CompatibleEncryptNodeConverter.java  |  38 ++---
 .../metadata/converter/EncryptNodeConverter.java   |  38 ++---
 ...lCompatibleEncryptRuleConfigurationSwapper.java |  12 +-
 .../NewYamlEncryptRuleConfigurationSwapper.java    |  12 +-
 .../event/MaskRuleConfigurationEventBuilder.java   |   9 +-
 .../mask/metadata/converter/MaskNodeConverter.java |  38 ++---
 .../NewYamlMaskRuleConfigurationSwapper.java       |  12 +-
 ...riteSplittingRuleConfigurationEventBuilder.java |   9 +-
 .../converter/ReadwriteSplittingNodeConverter.java |  38 ++---
 ...ReadwriteSplittingRuleConfigurationSwapper.java |  14 +-
 .../event/ShadowRuleConfigurationEventBuilder.java |  13 +-
 .../metadata/converter/ShadowNodeConverter.java    |  61 ++------
 .../NewYamlShadowRuleConfigurationSwapper.java     |  22 +--
 .../ShardingRuleConfigurationEventBuilder.java     |  29 ++--
 .../metadata/converter/ShardingNodeConverter.java  | 157 ++++-----------------
 .../NewYamlShardingRuleConfigurationSwapper.java   |  59 ++++----
 .../infra/metadata/nodepath/RuleNodePath.java      |  87 ++++++++++++
 .../nodepath/item/NamedRuleItemNodePath.java       |   2 +-
 .../nodepath/item/UniqueRuleItemNodePath.java      |   2 +-
 .../nodepath/{ => root}/RuleRootNodePath.java      |   2 +-
 .../nodepath/item/NamedRuleItemNodePathTest.java   |   2 +-
 .../nodepath/{ => root}/RuleRootNodePathTest.java  |   2 +-
 .../event/SingleRuleConfigurationEventBuilder.java |   7 +-
 .../metadata/converter/SingleNodeConverter.java    |  28 ++--
 .../NewYamlSingleRuleConfigurationSwapper.java     |   7 +-
 30 files changed, 341 insertions(+), 430 deletions(-)

diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/event/BroadcastRuleConfigurationEventBuilder.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/event/BroadcastRuleConfigurationEventBuilder.java
index 2a8d3d56197..16da5247745 100644
--- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/event/BroadcastRuleConfigurationEventBuilder.java
+++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/event/BroadcastRuleConfigurationEventBuilder.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.broadcast.event.config.AddBroadcastTableEvent;
 import org.apache.shardingsphere.broadcast.event.config.AlterBroadcastTableEvent;
 import org.apache.shardingsphere.broadcast.event.config.DeleteBroadcastTableEvent;
 import org.apache.shardingsphere.broadcast.metadata.converter.BroadcastNodeConverter;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -34,12 +35,14 @@ import java.util.Optional;
  */
 public final class BroadcastRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath broadcastRuleNodePath = BroadcastNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!BroadcastNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!broadcastRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        if (BroadcastNodeConverter.getTableNodePath().getNameByActiveVersion(event.getKey()).isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
+        if (broadcastRuleNodePath.getNamedRuleItemNodePath(BroadcastNodeConverter.TABLES).getNameByActiveVersion(event.getKey()).isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createBroadcastConfigEvent(databaseName, event);
         }
         return Optional.empty();
diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/metadata/converter/BroadcastNodeConverter.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/metadata/converter/BroadcastNodeConverter.java
index 95ee44cb736..d426bd3524e 100644
--- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/metadata/converter/BroadcastNodeConverter.java
+++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/metadata/converter/BroadcastNodeConverter.java
@@ -19,8 +19,9 @@ package org.apache.shardingsphere.broadcast.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Collections;
 
 /**
  * Broadcast node converter.
@@ -28,36 +29,16 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class BroadcastNodeConverter {
     
-    private static final String TABLES_NODE = "tables";
-    
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("broadcast");
-    
-    private static final NamedRuleItemNodePath TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, TABLES_NODE);
-    
-    /**
-     * Get rule root node path.
-     *
-     * @return rule root node path
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
+    public static final String TABLES = "tables";
     
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static NamedRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("broadcast", Collections.singleton(TABLES), Collections.emptyList());
     
     /**
-     * Get tables path.
-     *
-     * @return tables path
+     * Get instance of rule node path.
+     * 
+     * @return got instance
      */
-    public static String getTablesPath() {
-        return TABLES_NODE;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/yaml/swapper/NewYamlBroadcastRuleConfigurationSwapper.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/yaml/swapper/NewYamlBroadcastRuleConfigurationSwapper.java
index 287f08f4fd6..5aaa0c8e03d 100644
--- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/yaml/swapper/NewYamlBroadcastRuleConfigurationSwapper.java
+++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/yaml/swapper/NewYamlBroadcastRuleConfigurationSwapper.java
@@ -21,6 +21,7 @@ import org.apache.shardingsphere.broadcast.api.config.BroadcastRuleConfiguration
 import org.apache.shardingsphere.broadcast.constant.BroadcastOrder;
 import org.apache.shardingsphere.broadcast.metadata.converter.BroadcastNodeConverter;
 import org.apache.shardingsphere.broadcast.yaml.config.YamlBroadcastRuleConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.swapper.rule.NewYamlRuleConfigurationSwapper;
@@ -34,6 +35,8 @@ import java.util.Collections;
  */
 public final class NewYamlBroadcastRuleConfigurationSwapper implements NewYamlRuleConfigurationSwapper<BroadcastRuleConfiguration> {
     
+    private final RuleNodePath broadcastRuleNodePath = BroadcastNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final BroadcastRuleConfiguration data) {
         if (data.getTables().isEmpty()) {
@@ -41,13 +44,13 @@ public final class NewYamlBroadcastRuleConfigurationSwapper implements NewYamlRu
         }
         YamlBroadcastRuleConfiguration yamlBroadcastRuleConfiguration = new YamlBroadcastRuleConfiguration();
         yamlBroadcastRuleConfiguration.getTables().addAll(data.getTables());
-        return Collections.singleton(new YamlDataNode(BroadcastNodeConverter.getTablesPath(), YamlEngine.marshal(yamlBroadcastRuleConfiguration)));
+        return Collections.singleton(new YamlDataNode(BroadcastNodeConverter.TABLES, YamlEngine.marshal(yamlBroadcastRuleConfiguration)));
     }
     
     @Override
     public BroadcastRuleConfiguration swapToObject(final Collection<YamlDataNode> dataNodes) {
         for (YamlDataNode each : dataNodes) {
-            if (BroadcastNodeConverter.getRuleRootNodePath().isValidatedPath(each.getKey())) {
+            if (broadcastRuleNodePath.getRootNodePath().isValidatedPath(each.getKey())) {
                 YamlBroadcastRuleConfiguration yamlBroadcastRuleConfiguration = YamlEngine.unmarshal(each.getValue(), YamlBroadcastRuleConfiguration.class);
                 return new BroadcastRuleConfiguration(yamlBroadcastRuleConfiguration.getTables());
             }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/CompatibleEncryptRuleConfigurationEventBuilder.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/CompatibleEncryptRuleConfigurationEventBuilder.java
index 7b43557da67..bdcb0932939 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/CompatibleEncryptRuleConfigurationEventBuilder.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/CompatibleEncryptRuleConfigurationEventBuilder.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.encrypt.event.compatible.table.AddCompatibleEnc
 import org.apache.shardingsphere.encrypt.event.compatible.table.AlterCompatibleEncryptTableEvent;
 import org.apache.shardingsphere.encrypt.event.compatible.table.DeleteCompatibleEncryptTableEvent;
 import org.apache.shardingsphere.encrypt.metadata.converter.CompatibleEncryptNodeConverter;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -38,16 +39,18 @@ import java.util.Optional;
 @Deprecated
 public final class CompatibleEncryptRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath encryptRuleNodePath = CompatibleEncryptNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!CompatibleEncryptNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!encryptRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        Optional<String> tableName = CompatibleEncryptNodeConverter.getTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> tableName = encryptRuleNodePath.getNamedRuleItemNodePath(CompatibleEncryptNodeConverter.TABLES).getNameByActiveVersion(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createEncryptConfigEvent(databaseName, tableName.get(), event);
         }
-        Optional<String> encryptorName = CompatibleEncryptNodeConverter.getEncryptorNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> encryptorName = encryptRuleNodePath.getNamedRuleItemNodePath(CompatibleEncryptNodeConverter.ENCRYPTORS).getNameByActiveVersion(event.getKey());
         if (encryptorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createEncryptorEvent(databaseName, encryptorName.get(), event);
         }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java
index def19989bdc..3d45dc9f70c 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.encrypt.event.table.AddEncryptTableEvent;
 import org.apache.shardingsphere.encrypt.event.table.AlterEncryptTableEvent;
 import org.apache.shardingsphere.encrypt.event.table.DeleteEncryptTableEvent;
 import org.apache.shardingsphere.encrypt.metadata.converter.EncryptNodeConverter;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -36,16 +37,18 @@ import java.util.Optional;
  */
 public final class EncryptRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath encryptRuleNodePath = EncryptNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!EncryptNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!encryptRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        Optional<String> tableName = EncryptNodeConverter.getTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> tableName = encryptRuleNodePath.getNamedRuleItemNodePath(EncryptNodeConverter.TABLES).getNameByActiveVersion(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createEncryptConfigEvent(databaseName, tableName.get(), event);
         }
-        Optional<String> encryptorName = EncryptNodeConverter.getEncryptorNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> encryptorName = encryptRuleNodePath.getNamedRuleItemNodePath(EncryptNodeConverter.ENCRYPTORS).getNameByActiveVersion(event.getKey());
         if (encryptorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createEncryptorEvent(databaseName, encryptorName.get(), event);
         }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/CompatibleEncryptNodeConverter.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/CompatibleEncryptNodeConverter.java
index 62be882beb5..896ba7e3a7f 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/CompatibleEncryptNodeConverter.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/CompatibleEncryptNodeConverter.java
@@ -19,8 +19,10 @@ package org.apache.shardingsphere.encrypt.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Compatible encrypt node converter.
@@ -30,36 +32,18 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class CompatibleEncryptNodeConverter {
     
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("compatible_encrypt");
-    
-    private static final NamedRuleItemNodePath TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "tables");
+    public static final String TABLES = "tables";
     
-    private static final NamedRuleItemNodePath ENCRYPTOR_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "encryptors");
+    public static final String ENCRYPTORS = "encryptors";
     
-    /**
-     * Get rule root node path.
-     *
-     * @return rule root node path
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
-    
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static NamedRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("compatible_encrypt", Arrays.asList(TABLES, ENCRYPTORS), Collections.emptyList());
     
     /**
-     * Get encryptor node path.
+     * Get instance of rule node path.
      *
-     * @return encryptor node path
+     * @return got instance
      */
-    public static NamedRuleItemNodePath getEncryptorNodePath() {
-        return ENCRYPTOR_NODE_PATH;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java
index 66aecfb72f9..9f7719392d3 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java
@@ -19,8 +19,10 @@ package org.apache.shardingsphere.encrypt.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Encrypt node converter.
@@ -28,36 +30,18 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class EncryptNodeConverter {
     
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("encrypt");
-    
-    private static final NamedRuleItemNodePath TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "tables");
+    public static final String TABLES = "tables";
     
-    private static final NamedRuleItemNodePath ENCRYPTOR_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "encryptors");
+    public static final String ENCRYPTORS = "encryptors";
     
-    /**
-     * Get rule root node converter.
-     *
-     * @return rule root node converter
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
-    
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static NamedRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("encrypt", Arrays.asList(TABLES, ENCRYPTORS), Collections.emptyList());
     
     /**
-     * Get encryptor node path.
+     * Get instance of rule node path.
      *
-     * @return encryptor node path
+     * @return got instance
      */
-    public static NamedRuleItemNodePath getEncryptorNodePath() {
-        return ENCRYPTOR_NODE_PATH;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapper.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapper.java
index f03c140d676..d8c354a4c8a 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapper.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlCompatibleEncryptRuleConfigurationSwapper.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.encrypt.metadata.converter.CompatibleEncryptNod
 import org.apache.shardingsphere.encrypt.yaml.config.rule.YamlCompatibleEncryptTableRuleConfiguration;
 import org.apache.shardingsphere.encrypt.yaml.swapper.rule.YamlCompatibleEncryptTableRuleConfigurationSwapper;
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmConfiguration;
@@ -50,15 +51,18 @@ public final class NewYamlCompatibleEncryptRuleConfigurationSwapper implements N
     
     private final YamlAlgorithmConfigurationSwapper algorithmSwapper = new YamlAlgorithmConfigurationSwapper();
     
+    private final RuleNodePath encryptRuleNodePath = CompatibleEncryptNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final CompatibleEncryptRuleConfiguration data) {
         Collection<YamlDataNode> result = new LinkedHashSet<>();
         for (Entry<String, AlgorithmConfiguration> entry : data.getEncryptors().entrySet()) {
-            result.add(new YamlDataNode(CompatibleEncryptNodeConverter.getEncryptorNodePath().getPath(entry.getKey()),
+            result.add(new YamlDataNode(encryptRuleNodePath.getNamedRuleItemNodePath(CompatibleEncryptNodeConverter.ENCRYPTORS).getPath(entry.getKey()),
                     YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
         }
         for (EncryptTableRuleConfiguration each : data.getTables()) {
-            result.add(new YamlDataNode(CompatibleEncryptNodeConverter.getTableNodePath().getPath(each.getName()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
+            result.add(new YamlDataNode(
+                    encryptRuleNodePath.getNamedRuleItemNodePath(CompatibleEncryptNodeConverter.TABLES).getPath(each.getName()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
         }
         return result;
     }
@@ -68,9 +72,9 @@ public final class NewYamlCompatibleEncryptRuleConfigurationSwapper implements N
         Collection<EncryptTableRuleConfiguration> tables = new LinkedList<>();
         Map<String, AlgorithmConfiguration> encryptors = new HashMap<>();
         for (YamlDataNode each : dataNodes) {
-            CompatibleEncryptNodeConverter.getTableNodePath().getName(each.getKey())
+            encryptRuleNodePath.getNamedRuleItemNodePath(CompatibleEncryptNodeConverter.TABLES).getName(each.getKey())
                     .ifPresent(optional -> tables.add(tableSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlCompatibleEncryptTableRuleConfiguration.class))));
-            CompatibleEncryptNodeConverter.getEncryptorNodePath().getName(each.getKey())
+            encryptRuleNodePath.getNamedRuleItemNodePath(CompatibleEncryptNodeConverter.ENCRYPTORS).getName(each.getKey())
                     .ifPresent(optional -> encryptors.put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
         }
         return new CompatibleEncryptRuleConfiguration(tables, encryptors);
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapper.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapper.java
index c9071e7adf5..ac008cac618 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapper.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/NewYamlEncryptRuleConfigurationSwapper.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.encrypt.metadata.converter.EncryptNodeConverter
 import org.apache.shardingsphere.encrypt.yaml.config.rule.YamlEncryptTableRuleConfiguration;
 import org.apache.shardingsphere.encrypt.yaml.swapper.rule.YamlEncryptTableRuleConfigurationSwapper;
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmConfiguration;
@@ -47,15 +48,18 @@ public final class NewYamlEncryptRuleConfigurationSwapper implements NewYamlRule
     
     private final YamlAlgorithmConfigurationSwapper algorithmSwapper = new YamlAlgorithmConfigurationSwapper();
     
+    private final RuleNodePath encryptRuleNodePath = EncryptNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final EncryptRuleConfiguration data) {
         Collection<YamlDataNode> result = new LinkedHashSet<>();
         for (Entry<String, AlgorithmConfiguration> entry : data.getEncryptors().entrySet()) {
-            result.add(new YamlDataNode(EncryptNodeConverter.getEncryptorNodePath().getPath(entry.getKey()),
+            result.add(new YamlDataNode(encryptRuleNodePath.getNamedRuleItemNodePath(EncryptNodeConverter.ENCRYPTORS).getPath(entry.getKey()),
                     YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
         }
         for (EncryptTableRuleConfiguration each : data.getTables()) {
-            result.add(new YamlDataNode(EncryptNodeConverter.getTableNodePath().getPath(each.getName()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
+            result.add(new YamlDataNode(encryptRuleNodePath.getNamedRuleItemNodePath(EncryptNodeConverter.TABLES).getPath(each.getName()),
+                    YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
         }
         return result;
     }
@@ -65,9 +69,9 @@ public final class NewYamlEncryptRuleConfigurationSwapper implements NewYamlRule
         Collection<EncryptTableRuleConfiguration> tables = new LinkedList<>();
         Map<String, AlgorithmConfiguration> encryptors = new HashMap<>();
         for (YamlDataNode each : dataNodes) {
-            EncryptNodeConverter.getTableNodePath().getName(each.getKey())
+            encryptRuleNodePath.getNamedRuleItemNodePath(EncryptNodeConverter.TABLES).getName(each.getKey())
                     .ifPresent(optional -> tables.add(tableSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlEncryptTableRuleConfiguration.class))));
-            EncryptNodeConverter.getEncryptorNodePath().getName(each.getKey())
+            encryptRuleNodePath.getNamedRuleItemNodePath(EncryptNodeConverter.ENCRYPTORS).getName(each.getKey())
                     .ifPresent(optional -> encryptors.put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
         }
         return new EncryptRuleConfiguration(tables, encryptors);
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java
index b498cfc53e2..d3abe6eb603 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.mask.event;
 
 import com.google.common.base.Strings;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mask.event.algorithm.AlterMaskAlgorithmEvent;
 import org.apache.shardingsphere.mask.event.algorithm.DeleteMaskAlgorithmEvent;
@@ -36,16 +37,18 @@ import java.util.Optional;
  */
 public final class MaskRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath maskRuleNodePath = MaskNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!MaskNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!maskRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        Optional<String> tableName = MaskNodeConverter.getTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> tableName = maskRuleNodePath.getNamedRuleItemNodePath(MaskNodeConverter.TABLES).getNameByActiveVersion(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createMaskConfigEvent(databaseName, tableName.get(), event);
         }
-        Optional<String> algorithmName = MaskNodeConverter.getAlgorithmNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> algorithmName = maskRuleNodePath.getNamedRuleItemNodePath(MaskNodeConverter.ALGORITHMS).getNameByActiveVersion(event.getKey());
         if (algorithmName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createMaskAlgorithmEvent(databaseName, algorithmName.get(), event);
         }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java
index 2ccb4d3492f..b7a663a86db 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java
@@ -19,8 +19,10 @@ package org.apache.shardingsphere.mask.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Mask node converter.
@@ -28,36 +30,18 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class MaskNodeConverter {
     
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("mask");
-    
-    private static final NamedRuleItemNodePath TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "tables");
+    public static final String TABLES = "tables";
     
-    private static final NamedRuleItemNodePath ALGORITHM_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "algorithms");
+    public static final String ALGORITHMS = "algorithms";
     
-    /**
-     * Get rule root node path.
-     *
-     * @return rule root node path
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
-    
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static NamedRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("mask", Arrays.asList(TABLES, ALGORITHMS), Collections.emptyList());
     
     /**
-     * Get algorithm node path.
+     * Get instance of rule node path.
      *
-     * @return algorithm node path
+     * @return got instance
      */
-    public static NamedRuleItemNodePath getAlgorithmNodePath() {
-        return ALGORITHM_NODE_PATH;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapper.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapper.java
index e9360e91372..3a578aeebff 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapper.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/yaml/swapper/NewYamlMaskRuleConfigurationSwapper.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.mask.yaml.swapper;
 
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmConfiguration;
@@ -46,14 +47,17 @@ public final class NewYamlMaskRuleConfigurationSwapper implements NewYamlRuleCon
     
     private final YamlAlgorithmConfigurationSwapper algorithmSwapper = new YamlAlgorithmConfigurationSwapper();
     
+    private final RuleNodePath maskRuleNodePath = MaskNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final MaskRuleConfiguration data) {
         Collection<YamlDataNode> result = new LinkedHashSet<>();
         for (Map.Entry<String, AlgorithmConfiguration> entry : data.getMaskAlgorithms().entrySet()) {
-            result.add(new YamlDataNode(MaskNodeConverter.getAlgorithmNodePath().getPath(entry.getKey()), YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
+            result.add(new YamlDataNode(maskRuleNodePath.getNamedRuleItemNodePath(MaskNodeConverter.ALGORITHMS).getPath(entry.getKey()),
+                    YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
         }
         for (MaskTableRuleConfiguration each : data.getTables()) {
-            result.add(new YamlDataNode(MaskNodeConverter.getTableNodePath().getPath(each.getName()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
+            result.add(new YamlDataNode(maskRuleNodePath.getNamedRuleItemNodePath(MaskNodeConverter.TABLES).getPath(each.getName()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
         }
         return result;
     }
@@ -63,9 +67,9 @@ public final class NewYamlMaskRuleConfigurationSwapper implements NewYamlRuleCon
         Collection<MaskTableRuleConfiguration> tables = new LinkedList<>();
         Map<String, AlgorithmConfiguration> algorithms = new LinkedHashMap<>();
         for (YamlDataNode each : dataNodes) {
-            MaskNodeConverter.getTableNodePath().getName(each.getKey())
+            maskRuleNodePath.getNamedRuleItemNodePath(MaskNodeConverter.TABLES).getName(each.getKey())
                     .ifPresent(optional -> tables.add(tableSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlMaskTableRuleConfiguration.class))));
-            MaskNodeConverter.getAlgorithmNodePath().getName(each.getKey())
+            maskRuleNodePath.getNamedRuleItemNodePath(MaskNodeConverter.ALGORITHMS).getName(each.getKey())
                     .ifPresent(optional -> algorithms.put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
         }
         return new MaskRuleConfiguration(tables, algorithms);
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/event/ReadwriteSplittingRuleConfigurationEventBuilder.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/event/ReadwriteSplittingRuleConfigurationEventBuilder.java
index c531a8fa055..31dd2ee5ace 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/event/ReadwriteSplittingRuleConfigurationEventBuilder.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/event/ReadwriteSplittingRuleConfigurationEventBuilder.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.readwritesplitting.event;
 
 import com.google.common.base.Strings;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -36,16 +37,18 @@ import java.util.Optional;
  */
 public final class ReadwriteSplittingRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath readwriteSplittingRuleNodePath = ReadwriteSplittingNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!ReadwriteSplittingNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!readwriteSplittingRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        Optional<String> groupName = ReadwriteSplittingNodeConverter.getDataSourceNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> groupName = readwriteSplittingRuleNodePath.getNamedRuleItemNodePath(ReadwriteSplittingNodeConverter.DATA_SOURCES).getNameByActiveVersion(event.getKey());
         if (groupName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createReadwriteSplittingConfigEvent(databaseName, groupName.get(), event);
         }
-        Optional<String> loadBalancerName = ReadwriteSplittingNodeConverter.getLoadBalancerNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> loadBalancerName = readwriteSplittingRuleNodePath.getNamedRuleItemNodePath(ReadwriteSplittingNodeConverter.LOAD_BALANCERS).getNameByActiveVersion(event.getKey());
         if (loadBalancerName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createLoadBalanceEvent(databaseName, loadBalancerName.get(), event);
         }
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/metadata/converter/ReadwriteSplittingNodeConverter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/metadata/converter/ReadwriteSplittingNodeConverter.java
index 091365de174..49f3db5aa24 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/metadata/converter/ReadwriteSplittingNodeConverter.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/metadata/converter/ReadwriteSplittingNodeConverter.java
@@ -19,8 +19,10 @@ package org.apache.shardingsphere.readwritesplitting.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Readwrite-splitting node converter.
@@ -28,36 +30,18 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class ReadwriteSplittingNodeConverter {
     
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("readwrite_splitting");
-    
-    private static final NamedRuleItemNodePath DATA_SOURCE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "data_sources");
+    public static final String DATA_SOURCES = "data_sources";
     
-    private static final NamedRuleItemNodePath LOAD_BALANCER_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "load_balancers");
+    public static final String LOAD_BALANCERS = "load_balancers";
     
-    /**
-     * Get rule root node path.
-     *
-     * @return rule root node path
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
-    
-    /**
-     * Get data source node path.
-     *
-     * @return data source node path
-     */
-    public static NamedRuleItemNodePath getDataSourceNodePath() {
-        return DATA_SOURCE_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("readwrite_splitting", Arrays.asList(DATA_SOURCES, LOAD_BALANCERS), Collections.emptyList());
     
     /**
-     * Get load balancer node path.
+     * Get instance of rule node path.
      *
-     * @return load balancer node path
+     * @return got instance
      */
-    public static NamedRuleItemNodePath getLoadBalancerNodePath() {
-        return LOAD_BALANCER_NODE_PATH;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapper.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapper.java
index a681df41a08..f71f246a4ce 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapper.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/yaml/swapper/NewYamlReadwriteSplittingRuleConfigurationSwapper.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.readwritesplitting.yaml.swapper;
 
 import com.google.common.base.Strings;
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmConfiguration;
@@ -45,15 +46,18 @@ public final class NewYamlReadwriteSplittingRuleConfigurationSwapper implements
     
     private final YamlAlgorithmConfigurationSwapper algorithmSwapper = new YamlAlgorithmConfigurationSwapper();
     
+    private final RuleNodePath readwriteSplittingRuleNodePath = ReadwriteSplittingNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final ReadwriteSplittingRuleConfiguration data) {
         Collection<YamlDataNode> result = new LinkedHashSet<>();
         for (Map.Entry<String, AlgorithmConfiguration> entry : data.getLoadBalancers().entrySet()) {
-            result.add(new YamlDataNode(
-                    ReadwriteSplittingNodeConverter.getLoadBalancerNodePath().getPath(entry.getKey()), YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
+            result.add(new YamlDataNode(readwriteSplittingRuleNodePath.getNamedRuleItemNodePath(ReadwriteSplittingNodeConverter.LOAD_BALANCERS).getPath(entry.getKey()),
+                    YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
         }
         for (ReadwriteSplittingDataSourceRuleConfiguration each : data.getDataSources()) {
-            result.add(new YamlDataNode(ReadwriteSplittingNodeConverter.getDataSourceNodePath().getPath(each.getName()), YamlEngine.marshal(swapToYamlConfiguration(each))));
+            result.add(new YamlDataNode(readwriteSplittingRuleNodePath.getNamedRuleItemNodePath(ReadwriteSplittingNodeConverter.DATA_SOURCES).getPath(each.getName()),
+                    YamlEngine.marshal(swapToYamlConfiguration(each))));
         }
         return result;
     }
@@ -72,9 +76,9 @@ public final class NewYamlReadwriteSplittingRuleConfigurationSwapper implements
         Collection<ReadwriteSplittingDataSourceRuleConfiguration> dataSources = new LinkedList<>();
         Map<String, AlgorithmConfiguration> loadBalancerMap = new LinkedHashMap<>();
         for (YamlDataNode each : dataNodes) {
-            ReadwriteSplittingNodeConverter.getDataSourceNodePath().getName(each.getKey())
+            readwriteSplittingRuleNodePath.getNamedRuleItemNodePath(ReadwriteSplittingNodeConverter.DATA_SOURCES).getName(each.getKey())
                     .ifPresent(optional -> dataSources.add(swapDataSource(optional, YamlEngine.unmarshal(each.getValue(), YamlReadwriteSplittingDataSourceRuleConfiguration.class))));
-            ReadwriteSplittingNodeConverter.getLoadBalancerNodePath().getName(each.getKey())
+            readwriteSplittingRuleNodePath.getNamedRuleItemNodePath(ReadwriteSplittingNodeConverter.LOAD_BALANCERS).getName(each.getKey())
                     .ifPresent(optional -> loadBalancerMap.put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
         }
         return new ReadwriteSplittingRuleConfiguration(dataSources, loadBalancerMap);
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 403ed3ec8c6..4b482e43154 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
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.shadow.event;
 
 import com.google.common.base.Strings;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -41,24 +42,26 @@ import java.util.Optional;
  */
 public final class ShadowRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath shadowRuleNodePath = ShadowNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!ShadowNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!shadowRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        Optional<String> dataSourceName = ShadowNodeConverter.getDataSourceNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> dataSourceName = shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.DATA_SOURCES).getNameByActiveVersion(event.getKey());
         if (dataSourceName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShadowConfigEvent(databaseName, dataSourceName.get(), event);
         }
-        Optional<String> tableName = ShadowNodeConverter.getTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> tableName = shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.TABLES).getNameByActiveVersion(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShadowTableConfigEvent(databaseName, tableName.get(), event);
         }
-        Optional<String> algorithmName = ShadowNodeConverter.getAlgorithmNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> algorithmName = shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.ALGORITHMS).getNameByActiveVersion(event.getKey());
         if (algorithmName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShadowAlgorithmEvent(databaseName, algorithmName.get(), event);
         }
-        if (ShadowNodeConverter.getDefaultAlgorithmNameNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shadowRuleNodePath.getUniqueRuleItemNodePaths(ShadowNodeConverter.DEFAULT_ALGORITHM).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createDefaultShadowAlgorithmNameEvent(databaseName, event);
         }
         return Optional.empty();
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 7d26168b248..1448ac609b5 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
@@ -19,9 +19,10 @@ package org.apache.shardingsphere.shadow.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.UniqueRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Shadow node converter.
@@ -29,58 +30,22 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class ShadowNodeConverter {
     
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("shadow");
-    
-    private static final NamedRuleItemNodePath DATA_SOURCE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "data_sources");
+    public static final String DATA_SOURCES = "data_sources";
     
-    private static final NamedRuleItemNodePath TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "tables");
+    public static final String TABLES = "tables";
     
-    private static final NamedRuleItemNodePath ALGORITHM_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "algorithms");
+    public static final String ALGORITHMS = "algorithms";
     
-    private static final UniqueRuleItemNodePath DEFAULT_ALGORITHM_NAME_NODE_PATH = new UniqueRuleItemNodePath(ROOT_NODE_PATH, "default_algorithm_name");
+    public static final String DEFAULT_ALGORITHM = "default_algorithm_name";
     
-    /**
-     * Get rule root node path.
-     *
-     * @return rule root node path
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
-    
-    /**
-     * Get data source node path.
-     *
-     * @return data source node path
-     */
-    public static NamedRuleItemNodePath getDataSourceNodePath() {
-        return DATA_SOURCE_NODE_PATH;
-    }
-    
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static NamedRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
-    
-    /**
-     * Get algorithm node path.
-     *
-     * @return algorithm node path
-     */
-    public static NamedRuleItemNodePath getAlgorithmNodePath() {
-        return ALGORITHM_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("shadow", Arrays.asList(DATA_SOURCES, TABLES, ALGORITHMS), Collections.singleton(DEFAULT_ALGORITHM));
     
     /**
-     * Get default algorithm name node path.
+     * Get instance of rule node path.
      *
-     * @return default algorithm name node path
+     * @return got instance
      */
-    public static UniqueRuleItemNodePath getDefaultAlgorithmNameNodePath() {
-        return DEFAULT_ALGORITHM_NAME_NODE_PATH;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapper.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapper.java
index 53844083df8..8f4064a8fcb 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapper.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/yaml/swapper/NewYamlShadowRuleConfigurationSwapper.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.shadow.yaml.swapper;
 
 import com.google.common.base.Strings;
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmConfiguration;
@@ -47,20 +48,25 @@ public final class NewYamlShadowRuleConfigurationSwapper implements NewYamlRuleC
     
     private final YamlAlgorithmConfigurationSwapper algorithmSwapper = new YamlAlgorithmConfigurationSwapper();
     
+    private final RuleNodePath shadowRuleNodePath = ShadowNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final ShadowRuleConfiguration data) {
         Collection<YamlDataNode> result = new LinkedHashSet<>();
         for (Entry<String, AlgorithmConfiguration> entry : data.getShadowAlgorithms().entrySet()) {
-            result.add(new YamlDataNode(ShadowNodeConverter.getAlgorithmNodePath().getPath(entry.getKey()), YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
+            result.add(new YamlDataNode(shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.ALGORITHMS).getPath(entry.getKey()),
+                    YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(entry.getValue()))));
         }
         if (!Strings.isNullOrEmpty(data.getDefaultShadowAlgorithmName())) {
-            result.add(new YamlDataNode(ShadowNodeConverter.getDefaultAlgorithmNameNodePath().getPath(), data.getDefaultShadowAlgorithmName()));
+            result.add(new YamlDataNode(shadowRuleNodePath.getUniqueRuleItemNodePaths(ShadowNodeConverter.DEFAULT_ALGORITHM).getPath(), data.getDefaultShadowAlgorithmName()));
         }
         for (ShadowDataSourceConfiguration each : data.getDataSources()) {
-            result.add(new YamlDataNode(ShadowNodeConverter.getDataSourceNodePath().getPath(each.getName()), YamlEngine.marshal(swapToDataSourceYamlConfiguration(each))));
+            result.add(new YamlDataNode(shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.DATA_SOURCES).getPath(each.getName()),
+                    YamlEngine.marshal(swapToDataSourceYamlConfiguration(each))));
         }
         for (Entry<String, ShadowTableConfiguration> entry : data.getTables().entrySet()) {
-            result.add(new YamlDataNode(ShadowNodeConverter.getTableNodePath().getPath(entry.getKey()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(entry.getValue()))));
+            result.add(new YamlDataNode(shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.TABLES).getPath(entry.getKey()),
+                    YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(entry.getValue()))));
         }
         return result;
     }
@@ -76,13 +82,13 @@ public final class NewYamlShadowRuleConfigurationSwapper implements NewYamlRuleC
     public ShadowRuleConfiguration swapToObject(final Collection<YamlDataNode> dataNodes) {
         ShadowRuleConfiguration result = new ShadowRuleConfiguration();
         for (YamlDataNode each : dataNodes) {
-            ShadowNodeConverter.getDataSourceNodePath().getName(each.getKey())
+            shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.DATA_SOURCES).getName(each.getKey())
                     .ifPresent(optional -> result.getDataSources().add(swapDataSource(optional, YamlEngine.unmarshal(each.getValue(), YamlShadowDataSourceConfiguration.class))));
-            ShadowNodeConverter.getTableNodePath().getName(each.getKey())
+            shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.TABLES).getName(each.getKey())
                     .ifPresent(optional -> result.getTables().put(optional, tableSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlShadowTableConfiguration.class))));
-            ShadowNodeConverter.getAlgorithmNodePath().getName(each.getKey())
+            shadowRuleNodePath.getNamedRuleItemNodePath(ShadowNodeConverter.ALGORITHMS).getName(each.getKey())
                     .ifPresent(optional -> result.getShadowAlgorithms().put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
-            if (ShadowNodeConverter.getDefaultAlgorithmNameNodePath().isValidatedPath(each.getKey())) {
+            if (shadowRuleNodePath.getUniqueRuleItemNodePaths(ShadowNodeConverter.DEFAULT_ALGORITHM).isValidatedPath(each.getKey())) {
                 result.setDefaultShadowAlgorithmName(each.getValue());
             }
         }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java
index c40bfa6680d..12e78b78782 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.sharding.event;
 
 import com.google.common.base.Strings;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -61,51 +62,53 @@ import java.util.Optional;
  */
 public final class ShardingRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath shardingRuleNodePath = ShardingNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!ShardingNodeConverter.getRuleRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!shardingRuleNodePath.getRootNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        Optional<String> tableName = ShardingNodeConverter.getTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> tableName = shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.TABLES).getNameByActiveVersion(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShardingTableConfigEvent(databaseName, tableName.get(), event);
         }
-        Optional<String> autoTableName = ShardingNodeConverter.getAutoTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> autoTableName = shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.AUTO_TABLES).getNameByActiveVersion(event.getKey());
         if (autoTableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShardingAutoTableConfigEvent(databaseName, autoTableName.get(), event);
         }
-        Optional<String> bindingTableName = ShardingNodeConverter.getBindingTableNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> bindingTableName = shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.BINDING_TABLES).getNameByActiveVersion(event.getKey());
         if (bindingTableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShardingTableReferenceConfigEvent(databaseName, bindingTableName.get(), event);
         }
-        if (ShardingNodeConverter.getDefaultDatabaseStrategyNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_DATABASE_STRATEGY).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createDefaultDatabaseStrategyConfigEvent(databaseName, event);
         }
-        if (ShardingNodeConverter.getDefaultTableStrategyNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_TABLE_STRATEGY).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createDefaultTableStrategyConfigEvent(databaseName, event);
         }
-        if (ShardingNodeConverter.getDefaultKeyGenerateStrategyNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_KEY_GENERATE_STRATEGY).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createDefaultKeyGenerateStrategyConfigEvent(databaseName, event);
         }
-        if (ShardingNodeConverter.getDefaultAuditStrategyNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_AUDIT_STRATEGY).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createDefaultShardingAuditorStrategyConfigEvent(databaseName, event);
         }
-        if (ShardingNodeConverter.getDefaultShardingColumnNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_SHARDING_COLUMN).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createDefaultShardingColumnEvent(databaseName, event);
         }
-        Optional<String> algorithmName = ShardingNodeConverter.getAlgorithmNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> algorithmName = shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.ALGORITHMS).getNameByActiveVersion(event.getKey());
         if (algorithmName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createShardingAlgorithmEvent(databaseName, algorithmName.get(), event);
         }
-        Optional<String> keyGeneratorName = ShardingNodeConverter.getKeyGeneratorNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> keyGeneratorName = shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.KEY_GENERATORS).getNameByActiveVersion(event.getKey());
         if (keyGeneratorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createKeyGeneratorEvent(databaseName, keyGeneratorName.get(), event);
         }
-        Optional<String> auditorName = ShardingNodeConverter.getAuditorNodePath().getNameByActiveVersion(event.getKey());
+        Optional<String> auditorName = shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.AUDITORS).getNameByActiveVersion(event.getKey());
         if (auditorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
             return createAuditorEvent(databaseName, auditorName.get(), event);
         }
-        if (ShardingNodeConverter.getShardingCacheNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.SHARDING_CACHE).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createShardingCacheEvent(databaseName, event);
         }
         return Optional.empty();
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 f47ac2a5a32..0c5118242b1 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
@@ -19,9 +19,9 @@ package org.apache.shardingsphere.sharding.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.UniqueRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Arrays;
 
 /**
  * Sharding node converter.
@@ -29,151 +29,44 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class ShardingNodeConverter {
     
-    private static final String DEFAULT_STRATEGIES_NODE = "default_strategies";
-    
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("sharding");
-    
-    private static final NamedRuleItemNodePath TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "tables");
-    
-    private static final NamedRuleItemNodePath AUTO_TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "auto_tables");
+    public static final String TABLES = "tables";
     
-    private static final NamedRuleItemNodePath BINDING_TABLE_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "binding_tables");
+    public static final String AUTO_TABLES = "auto_tables";
     
-    private static final NamedRuleItemNodePath ALGORITHM_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "algorithms");
+    public static final String BINDING_TABLES = "binding_tables";
     
-    private static final NamedRuleItemNodePath KEY_GENERATOR_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "key_generators");
+    public static final String ALGORITHMS = "algorithms";
     
-    private static final NamedRuleItemNodePath AUDITOR_NODE_PATH = new NamedRuleItemNodePath(ROOT_NODE_PATH, "auditors");
+    public static final String KEY_GENERATORS = "key_generators";
     
-    private static final UniqueRuleItemNodePath DEFAULT_DATABASE_STRATEGY_NODE_PATH =
-            new UniqueRuleItemNodePath(ROOT_NODE_PATH, DEFAULT_STRATEGIES_NODE, "default_database_strategy");
+    public static final String AUDITORS = "auditors";
     
-    private static final UniqueRuleItemNodePath DEFAULT_TABLE_STRATEGY_NODE_PATH = new UniqueRuleItemNodePath(ROOT_NODE_PATH, DEFAULT_STRATEGIES_NODE, "default_table_strategy");
+    public static final String DEFAULT_DATABASE_STRATEGY = "default_database_strategy";
     
-    private static final UniqueRuleItemNodePath DEFAULT_KEY_GENERATE_STRATEGY_NODE_PATH =
-            new UniqueRuleItemNodePath(ROOT_NODE_PATH, DEFAULT_STRATEGIES_NODE, "default_key_generate_strategy");
+    public static final String DEFAULT_TABLE_STRATEGY = "default_table_strategy";
     
-    private static final UniqueRuleItemNodePath DEFAULT_AUDIT_STRATEGY_NODE_PATH = new UniqueRuleItemNodePath(ROOT_NODE_PATH, DEFAULT_STRATEGIES_NODE, "default_audit_strategy");
+    public static final String DEFAULT_KEY_GENERATE_STRATEGY = "default_key_generate_strategy";
     
-    private static final UniqueRuleItemNodePath DEFAULT_SHARDING_COLUMN_NODE_PATH =
-            new UniqueRuleItemNodePath(ROOT_NODE_PATH, DEFAULT_STRATEGIES_NODE, "default_sharding_column");
+    public static final String DEFAULT_AUDIT_STRATEGY = "default_audit_strategy";
     
-    private static final UniqueRuleItemNodePath SHARDING_CACHE_NODE_PATH = new UniqueRuleItemNodePath(ROOT_NODE_PATH, "sharding_cache");
+    public static final String DEFAULT_SHARDING_COLUMN = "default_sharding_column";
     
-    /**
-     * Get rule root node path.
-     *
-     * @return rule root node path
-     */
-    public static RuleRootNodePath getRuleRootNodePath() {
-        return ROOT_NODE_PATH;
-    }
+    public static final String SHARDING_CACHE = "sharding_cache";
     
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static NamedRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
+    private static final String DEFAULT_STRATEGIES_PREFIX = "default_strategies.";
     
-    /**
-     * Get auto table node path.
-     *
-     * @return auto table node path
-     */
-    public static NamedRuleItemNodePath getAutoTableNodePath() {
-        return AUTO_TABLE_NODE_PATH;
-    }
-    
-    /**
-     * Get binding table node path.
-     *
-     * @return binding table node path
-     */
-    public static NamedRuleItemNodePath getBindingTableNodePath() {
-        return BINDING_TABLE_NODE_PATH;
-    }
-    
-    /**
-     * Get algorithm node path.
-     *
-     * @return algorithm node path
-     */
-    public static NamedRuleItemNodePath getAlgorithmNodePath() {
-        return ALGORITHM_NODE_PATH;
-    }
-    
-    /**
-     * Get key generator node path.
-     *
-     * @return key generator node path
-     */
-    public static NamedRuleItemNodePath getKeyGeneratorNodePath() {
-        return KEY_GENERATOR_NODE_PATH;
-    }
-    
-    /**
-     * Get auditor node path.
-     *
-     * @return auditor node path
-     */
-    public static NamedRuleItemNodePath getAuditorNodePath() {
-        return AUDITOR_NODE_PATH;
-    }
-    
-    /**
-     * Get default database strategy node path.
-     *
-     * @return default database strategy node path
-     */
-    public static UniqueRuleItemNodePath getDefaultDatabaseStrategyNodePath() {
-        return DEFAULT_DATABASE_STRATEGY_NODE_PATH;
-    }
-    
-    /**
-     * Get default table strategy node path.
-     *
-     * @return default table strategy node path
-     */
-    public static UniqueRuleItemNodePath getDefaultTableStrategyNodePath() {
-        return DEFAULT_TABLE_STRATEGY_NODE_PATH;
-    }
-    
-    /**
-     * Get default key generate strategy node path.
-     *
-     * @return default key generate strategy node path
-     */
-    public static UniqueRuleItemNodePath getDefaultKeyGenerateStrategyNodePath() {
-        return DEFAULT_KEY_GENERATE_STRATEGY_NODE_PATH;
-    }
-    
-    /**
-     * Get default audit strategy node path.
-     *
-     * @return default table strategy node path
-     */
-    public static UniqueRuleItemNodePath getDefaultAuditStrategyNodePath() {
-        return DEFAULT_AUDIT_STRATEGY_NODE_PATH;
-    }
-    
-    /**
-     * Get default sharding column node path.
-     *
-     * @return default sharding column node path
-     */
-    public static UniqueRuleItemNodePath getDefaultShardingColumnNodePath() {
-        return DEFAULT_SHARDING_COLUMN_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("sharding",
+            Arrays.asList(TABLES, AUTO_TABLES, BINDING_TABLES, ALGORITHMS, KEY_GENERATORS, AUDITORS),
+            Arrays.asList(DEFAULT_STRATEGIES_PREFIX + DEFAULT_DATABASE_STRATEGY, DEFAULT_STRATEGIES_PREFIX + DEFAULT_TABLE_STRATEGY,
+                    DEFAULT_STRATEGIES_PREFIX + DEFAULT_KEY_GENERATE_STRATEGY, DEFAULT_STRATEGIES_PREFIX + DEFAULT_AUDIT_STRATEGY, DEFAULT_STRATEGIES_PREFIX + DEFAULT_SHARDING_COLUMN,
+                    SHARDING_CACHE));
     
     /**
-     * Get sharding cache node path.
+     * Get instance of rule node path.
      *
-     * @return sharding cache node path
+     * @return got instance
      */
-    public static UniqueRuleItemNodePath getShardingCacheNodePath() {
-        return SHARDING_CACHE_NODE_PATH;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapper.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapper.java
index 5eee2f0b95e..397886a564a 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapper.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/yaml/swapper/NewYamlShardingRuleConfigurationSwapper.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.sharding.yaml.swapper;
 
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmConfiguration;
@@ -67,6 +68,8 @@ public final class NewYamlShardingRuleConfigurationSwapper implements NewYamlRul
     
     private final YamlShardingCacheConfigurationSwapper shardingCacheYamlSwapper = new YamlShardingCacheConfigurationSwapper();
     
+    private final RuleNodePath shardingRuleNodePath = ShardingNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final ShardingRuleConfiguration data) {
         Collection<YamlDataNode> result = new LinkedHashSet<>();
@@ -74,10 +77,10 @@ public final class NewYamlShardingRuleConfigurationSwapper implements NewYamlRul
         swapStrategies(data, result);
         swapTableRules(data, result);
         if (null != data.getDefaultShardingColumn()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getDefaultShardingColumnNodePath().getPath(), data.getDefaultShardingColumn()));
+            result.add(new YamlDataNode(shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_SHARDING_COLUMN).getPath(), data.getDefaultShardingColumn()));
         }
         if (null != data.getShardingCache()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getShardingCacheNodePath().getPath(),
+            result.add(new YamlDataNode(shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.SHARDING_CACHE).getPath(),
                     YamlEngine.marshal(shardingCacheYamlSwapper.swapToYamlConfiguration(data.getShardingCache()))));
         }
         return result;
@@ -85,46 +88,50 @@ public final class NewYamlShardingRuleConfigurationSwapper implements NewYamlRul
     
     private void swapAlgorithms(final ShardingRuleConfiguration data, final Collection<YamlDataNode> result) {
         for (Entry<String, AlgorithmConfiguration> each : data.getShardingAlgorithms().entrySet()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getAlgorithmNodePath().getPath(each.getKey()), YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(each.getValue()))));
+            result.add(new YamlDataNode(shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.ALGORITHMS).getPath(each.getKey()),
+                    YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(each.getValue()))));
         }
         for (Entry<String, AlgorithmConfiguration> each : data.getKeyGenerators().entrySet()) {
-            result.add(new YamlDataNode(
-                    ShardingNodeConverter.getKeyGeneratorNodePath().getPath(each.getKey()), YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(each.getValue()))));
+            result.add(new YamlDataNode(shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.KEY_GENERATORS).getPath(each.getKey()),
+                    YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(each.getValue()))));
         }
         for (Entry<String, AlgorithmConfiguration> each : data.getAuditors().entrySet()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getAuditorNodePath().getPath(each.getKey()), YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(each.getValue()))));
+            result.add(new YamlDataNode(shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.AUDITORS).getPath(each.getKey()),
+                    YamlEngine.marshal(algorithmSwapper.swapToYamlConfiguration(each.getValue()))));
         }
     }
     
     private void swapStrategies(final ShardingRuleConfiguration data, final Collection<YamlDataNode> result) {
         if (null != data.getDefaultDatabaseShardingStrategy()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getDefaultDatabaseStrategyNodePath().getPath(),
+            result.add(new YamlDataNode(shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_DATABASE_STRATEGY).getPath(),
                     YamlEngine.marshal(shardingStrategySwapper.swapToYamlConfiguration(data.getDefaultDatabaseShardingStrategy()))));
         }
         if (null != data.getDefaultTableShardingStrategy()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getDefaultTableStrategyNodePath().getPath(),
+            result.add(new YamlDataNode(shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_TABLE_STRATEGY).getPath(),
                     YamlEngine.marshal(shardingStrategySwapper.swapToYamlConfiguration(data.getDefaultTableShardingStrategy()))));
         }
         if (null != data.getDefaultKeyGenerateStrategy()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getDefaultKeyGenerateStrategyNodePath().getPath(),
+            result.add(new YamlDataNode(shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_KEY_GENERATE_STRATEGY).getPath(),
                     YamlEngine.marshal(keyGenerateStrategySwapper.swapToYamlConfiguration(data.getDefaultKeyGenerateStrategy()))));
         }
         if (null != data.getDefaultAuditStrategy()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getDefaultAuditStrategyNodePath().getPath(),
+            result.add(new YamlDataNode(shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_AUDIT_STRATEGY).getPath(),
                     YamlEngine.marshal(auditStrategySwapper.swapToYamlConfiguration(data.getDefaultAuditStrategy()))));
         }
     }
     
     private void swapTableRules(final ShardingRuleConfiguration data, final Collection<YamlDataNode> result) {
         for (ShardingTableRuleConfiguration each : data.getTables()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getTableNodePath().getPath(each.getLogicTable()), YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
+            result.add(new YamlDataNode(shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.TABLES).getPath(each.getLogicTable()),
+                    YamlEngine.marshal(tableSwapper.swapToYamlConfiguration(each))));
         }
         for (ShardingAutoTableRuleConfiguration each : data.getAutoTables()) {
-            result.add(new YamlDataNode(ShardingNodeConverter.getAutoTableNodePath().getPath(each.getLogicTable()), YamlEngine.marshal(autoTableYamlSwapper.swapToYamlConfiguration(each))));
+            result.add(new YamlDataNode(shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.AUTO_TABLES).getPath(each.getLogicTable()),
+                    YamlEngine.marshal(autoTableYamlSwapper.swapToYamlConfiguration(each))));
         }
         for (ShardingTableReferenceRuleConfiguration each : data.getBindingTableGroups()) {
-            result.add(new YamlDataNode(
-                    ShardingNodeConverter.getBindingTableNodePath().getPath(each.getName()), YamlShardingTableReferenceRuleConfigurationConverter.convertToYamlString(each)));
+            result.add(new YamlDataNode(shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.BINDING_TABLES).getPath(each.getName()),
+                    YamlShardingTableReferenceRuleConfigurationConverter.convertToYamlString(each)));
         }
     }
     
@@ -132,29 +139,29 @@ public final class NewYamlShardingRuleConfigurationSwapper implements NewYamlRul
     public ShardingRuleConfiguration swapToObject(final Collection<YamlDataNode> dataNodes) {
         ShardingRuleConfiguration result = new ShardingRuleConfiguration();
         for (YamlDataNode each : dataNodes) {
-            ShardingNodeConverter.getTableNodePath().getName(each.getKey())
+            shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.TABLES).getName(each.getKey())
                     .ifPresent(optional -> result.getTables().add(tableSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlTableRuleConfiguration.class))));
-            ShardingNodeConverter.getAutoTableNodePath().getName(each.getKey())
+            shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.AUTO_TABLES).getName(each.getKey())
                     .ifPresent(optional -> result.getAutoTables().add(autoTableYamlSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlShardingAutoTableRuleConfiguration.class))));
-            ShardingNodeConverter.getBindingTableNodePath().getName(each.getKey())
+            shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.BINDING_TABLES).getName(each.getKey())
                     .ifPresent(optional -> result.getBindingTableGroups().add(YamlShardingTableReferenceRuleConfigurationConverter.convertToObject(each.getValue())));
-            ShardingNodeConverter.getAlgorithmNodePath().getName(each.getKey())
+            shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.ALGORITHMS).getName(each.getKey())
                     .ifPresent(optional -> result.getShardingAlgorithms().put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
-            ShardingNodeConverter.getKeyGeneratorNodePath().getName(each.getKey())
+            shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.KEY_GENERATORS).getName(each.getKey())
                     .ifPresent(optional -> result.getKeyGenerators().put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
-            ShardingNodeConverter.getAuditorNodePath().getName(each.getKey())
+            shardingRuleNodePath.getNamedRuleItemNodePath(ShardingNodeConverter.AUDITORS).getName(each.getKey())
                     .ifPresent(optional -> result.getAuditors().put(optional, algorithmSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlAlgorithmConfiguration.class))));
-            if (ShardingNodeConverter.getDefaultDatabaseStrategyNodePath().isValidatedPath(each.getKey())) {
+            if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_DATABASE_STRATEGY).isValidatedPath(each.getKey())) {
                 result.setDefaultDatabaseShardingStrategy(shardingStrategySwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlShardingStrategyConfiguration.class)));
-            } else if (ShardingNodeConverter.getDefaultTableStrategyNodePath().isValidatedPath(each.getKey())) {
+            } else if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_TABLE_STRATEGY).isValidatedPath(each.getKey())) {
                 result.setDefaultTableShardingStrategy(shardingStrategySwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlShardingStrategyConfiguration.class)));
-            } else if (ShardingNodeConverter.getDefaultKeyGenerateStrategyNodePath().isValidatedPath(each.getKey())) {
+            } else if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_KEY_GENERATE_STRATEGY).isValidatedPath(each.getKey())) {
                 result.setDefaultKeyGenerateStrategy(keyGenerateStrategySwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlKeyGenerateStrategyConfiguration.class)));
-            } else if (ShardingNodeConverter.getDefaultAuditStrategyNodePath().isValidatedPath(each.getKey())) {
+            } else if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_AUDIT_STRATEGY).isValidatedPath(each.getKey())) {
                 result.setDefaultAuditStrategy(auditStrategySwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlShardingAuditStrategyConfiguration.class)));
-            } else if (ShardingNodeConverter.getDefaultShardingColumnNodePath().isValidatedPath(each.getKey())) {
+            } else if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.DEFAULT_SHARDING_COLUMN).isValidatedPath(each.getKey())) {
                 result.setDefaultShardingColumn(each.getValue());
-            } else if (ShardingNodeConverter.getShardingCacheNodePath().isValidatedPath(each.getKey())) {
+            } else if (shardingRuleNodePath.getUniqueRuleItemNodePaths(ShardingNodeConverter.SHARDING_CACHE).isValidatedPath(each.getKey())) {
                 result.setShardingCache(shardingCacheYamlSwapper.swapToObject(YamlEngine.unmarshal(each.getValue(), YamlShardingCacheConfiguration.class)));
             }
         }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleNodePath.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleNodePath.java
new file mode 100644
index 00000000000..7eaaf9c0ae8
--- /dev/null
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleNodePath.java
@@ -0,0 +1,87 @@
+/*
+ * 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.infra.metadata.nodepath;
+
+import lombok.Getter;
+import org.apache.shardingsphere.infra.metadata.nodepath.item.NamedRuleItemNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.item.UniqueRuleItemNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.root.RuleRootNodePath;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Rule node path.
+ */
+public final class RuleNodePath {
+    
+    @Getter
+    private final RuleRootNodePath rootNodePath;
+    
+    private final Map<String, NamedRuleItemNodePath> namedRuleItemNodePaths;
+    
+    private final Map<String, UniqueRuleItemNodePath> uniqueRuleItemNodePaths;
+    
+    public RuleNodePath(final String ruleType, final Collection<String> namedRuleItemNodePathTypes, final Collection<String> uniqueRuleItemNodePathTypes) {
+        rootNodePath = new RuleRootNodePath(ruleType);
+        namedRuleItemNodePaths = getNamedRuleItemNodePathMap(namedRuleItemNodePathTypes);
+        uniqueRuleItemNodePaths = getUniqueRuleItemNodePathMap(uniqueRuleItemNodePathTypes);
+    }
+    
+    private Map<String, NamedRuleItemNodePath> getNamedRuleItemNodePathMap(final Collection<String> namedRuleItemNodePathTypes) {
+        Map<String, NamedRuleItemNodePath> result = new HashMap<>(namedRuleItemNodePathTypes.size(), 1F);
+        for (String each : namedRuleItemNodePathTypes) {
+            result.put(each, new NamedRuleItemNodePath(rootNodePath, each));
+        }
+        return result;
+    }
+    
+    private Map<String, UniqueRuleItemNodePath> getUniqueRuleItemNodePathMap(final Collection<String> uniqueRuleItemNodePathTypes) {
+        Map<String, UniqueRuleItemNodePath> result = new HashMap<>(uniqueRuleItemNodePathTypes.size(), 1F);
+        for (String each : uniqueRuleItemNodePathTypes) {
+            if (each.contains(".")) {
+                String[] values = each.split("\\.");
+                result.put(values[1], new UniqueRuleItemNodePath(rootNodePath, values[0], values[1]));
+            } else {
+                result.put(each, new UniqueRuleItemNodePath(rootNodePath, each));
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Get named rule item node path.
+     * 
+     * @param itemType item type
+     * @return named rule item node path
+     */
+    public NamedRuleItemNodePath getNamedRuleItemNodePath(final String itemType) {
+        return namedRuleItemNodePaths.get(itemType);
+    }
+    
+    /**
+     * Get unique rule item node path.
+     *
+     * @param itemType item type
+     * @return unique rule item node path
+     */
+    public UniqueRuleItemNodePath getUniqueRuleItemNodePaths(final String itemType) {
+        return uniqueRuleItemNodePaths.get(itemType);
+    }
+}
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePath.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePath.java
index 6dbc4a2c8a0..5ab63c1e09c 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePath.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePath.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.infra.metadata.nodepath.item;
 
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.root.RuleRootNodePath;
 
 import java.util.Optional;
 import java.util.regex.Matcher;
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/UniqueRuleItemNodePath.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/UniqueRuleItemNodePath.java
index f3f0a460da4..2f7a44c5d06 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/UniqueRuleItemNodePath.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/item/UniqueRuleItemNodePath.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.infra.metadata.nodepath.item;
 
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.root.RuleRootNodePath;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleRootNodePath.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/root/RuleRootNodePath.java
similarity index 96%
rename from infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleRootNodePath.java
rename to infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/root/RuleRootNodePath.java
index d4ed7cf33f0..0e484653729 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleRootNodePath.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/nodepath/root/RuleRootNodePath.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.metadata.nodepath;
+package org.apache.shardingsphere.infra.metadata.nodepath.root;
 
 import lombok.Getter;
 
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePathTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePathTest.java
index 5bb5f65a7b9..ce95cb2db01 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePathTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/item/NamedRuleItemNodePathTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.infra.metadata.nodepath.item;
 
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.root.RuleRootNodePath;
 import org.junit.jupiter.api.Test;
 
 import java.util.Optional;
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleRootNodePathTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/root/RuleRootNodePathTest.java
similarity index 96%
rename from infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleRootNodePathTest.java
rename to infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/root/RuleRootNodePathTest.java
index 8f494b59f82..7f82f6a4b9f 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/RuleRootNodePathTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/nodepath/root/RuleRootNodePathTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.metadata.nodepath;
+package org.apache.shardingsphere.infra.metadata.nodepath.root;
 
 import org.junit.jupiter.api.Test;
 
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/event/SingleRuleConfigurationEventBuilder.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/event/SingleRuleConfigurationEventBuilder.java
index b3786717dab..bfa0767ae39 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/event/SingleRuleConfigurationEventBuilder.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/event/SingleRuleConfigurationEventBuilder.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.single.event;
 
 import com.google.common.base.Strings;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent;
 import org.apache.shardingsphere.mode.event.DataChangedEvent.Type;
@@ -34,12 +35,14 @@ import java.util.Optional;
  */
 public final class SingleRuleConfigurationEventBuilder implements RuleConfigurationEventBuilder {
     
+    private final RuleNodePath singleRuleNodePath = SingleNodeConverter.getInstance();
+    
     @Override
     public Optional<GovernanceEvent> build(final String databaseName, final DataChangedEvent event) {
-        if (!SingleNodeConverter.getTableNodePath().isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
+        if (!singleRuleNodePath.getUniqueRuleItemNodePaths(SingleNodeConverter.TABLES).isValidatedPath(event.getKey()) || Strings.isNullOrEmpty(event.getValue())) {
             return Optional.empty();
         }
-        if (SingleNodeConverter.getTableNodePath().isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
+        if (singleRuleNodePath.getUniqueRuleItemNodePaths(SingleNodeConverter.TABLES).isActiveVersionPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
             return createSingleConfigEvent(databaseName, event);
         }
         return Optional.empty();
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/metadata/converter/SingleNodeConverter.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/metadata/converter/SingleNodeConverter.java
index 4fa3a53040c..f861f97feea 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/metadata/converter/SingleNodeConverter.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/metadata/converter/SingleNodeConverter.java
@@ -19,8 +19,9 @@ package org.apache.shardingsphere.single.metadata.converter;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.nodepath.item.UniqueRuleItemNodePath;
-import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
+
+import java.util.Collections;
 
 /**
  * Single node converter.
@@ -28,27 +29,16 @@ import org.apache.shardingsphere.infra.metadata.nodepath.RuleRootNodePath;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class SingleNodeConverter {
     
-    private static final String TABLES_NODE = "tables";
-    
-    private static final RuleRootNodePath ROOT_NODE_PATH = new RuleRootNodePath("single");
+    public static final String TABLES = "tables";
     
-    private static final UniqueRuleItemNodePath TABLE_NODE_PATH = new UniqueRuleItemNodePath(ROOT_NODE_PATH, "tables");
-    
-    /**
-     * Get table node path.
-     *
-     * @return table node path
-     */
-    public static UniqueRuleItemNodePath getTableNodePath() {
-        return TABLE_NODE_PATH;
-    }
+    private static final RuleNodePath INSTANCE = new RuleNodePath("single", Collections.emptyList(), Collections.singleton(TABLES));
     
     /**
-     * Get tables path.
+     * Get instance of rule node path.
      *
-     * @return tables path
+     * @return got instance
      */
-    public static String getTablesPath() {
-        return TABLES_NODE;
+    public static RuleNodePath getInstance() {
+        return INSTANCE;
     }
 }
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/yaml/config/swapper/NewYamlSingleRuleConfigurationSwapper.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/yaml/config/swapper/NewYamlSingleRuleConfigurationSwapper.java
index 932ad91b0ad..485a072e267 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/yaml/config/swapper/NewYamlSingleRuleConfigurationSwapper.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/yaml/config/swapper/NewYamlSingleRuleConfigurationSwapper.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.single.yaml.config.swapper;
 
+import org.apache.shardingsphere.infra.metadata.nodepath.RuleNodePath;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.util.yaml.datanode.YamlDataNode;
 import org.apache.shardingsphere.infra.yaml.config.swapper.rule.NewYamlRuleConfigurationSwapper;
@@ -34,9 +35,11 @@ import java.util.Collections;
  */
 public final class NewYamlSingleRuleConfigurationSwapper implements NewYamlRuleConfigurationSwapper<SingleRuleConfiguration> {
     
+    private final RuleNodePath singleRuleNodePath = SingleNodeConverter.getInstance();
+    
     @Override
     public Collection<YamlDataNode> swapToDataNodes(final SingleRuleConfiguration data) {
-        return Collections.singletonList(new YamlDataNode(SingleNodeConverter.getTablesPath(), YamlEngine.marshal(swapToYamlConfiguration(data))));
+        return Collections.singletonList(new YamlDataNode(SingleNodeConverter.TABLES, YamlEngine.marshal(swapToYamlConfiguration(data))));
     }
     
     private YamlSingleRuleConfiguration swapToYamlConfiguration(final SingleRuleConfiguration data) {
@@ -49,7 +52,7 @@ public final class NewYamlSingleRuleConfigurationSwapper implements NewYamlRuleC
     @Override
     public SingleRuleConfiguration swapToObject(final Collection<YamlDataNode> dataNodes) {
         for (YamlDataNode each : dataNodes) {
-            if (SingleNodeConverter.getTableNodePath().isValidatedPath(each.getKey())) {
+            if (singleRuleNodePath.getUniqueRuleItemNodePaths(SingleNodeConverter.TABLES).isValidatedPath(each.getKey())) {
                 return swapToObject(YamlEngine.unmarshal(each.getValue(), YamlSingleRuleConfiguration.class));
             }
         }