You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2023/03/06 07:55:09 UTC

[shardingsphere] branch master updated: Add test cases for ImportDatabaseConfigurationUpdater. (#24446)

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

jianglongtao 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 6953feeb208 Add test cases for ImportDatabaseConfigurationUpdater. (#24446)
6953feeb208 is described below

commit 6953feeb2089be0ec7cae85e03a43296ef20b806
Author: yx9o <ya...@163.com>
AuthorDate: Mon Mar 6 15:55:01 2023 +0800

    Add test cases for ImportDatabaseConfigurationUpdater. (#24446)
    
    * Add test cases for ImportDatabaseConfigurationUpdater.
    
    * Add exception cases.
    
    * Update
---
 .../ImportDatabaseConfigurationUpdater.java        |   6 +-
 .../ral/updatable/ImportMetaDataUpdater.java       |   6 +-
 ...> YamlDatabaseConfigurationImportExecutor.java} |  67 ++++-----
 .../ImportDatabaseConfigurationUpdaterTest.java    | 165 ++++++++++++---------
 .../conf/import/config-database-discovery.yaml     |   2 +-
 ...ing.yaml => config-duplicated-logic-table.yaml} |  21 ++-
 .../conf/import/config-empty-data-source.yaml      |  18 +++
 ...ncrypt.yaml => config-empty-database-name.yaml} |  27 +---
 .../test/resources/conf/import/config-encrypt.yaml |   5 +-
 ...sharding.yaml => config-invalid-algorithm.yaml} |  13 +-
 .../test/resources/conf/import/config-mask.yaml    |   5 +-
 .../test/resources/conf/import/config-shadow.yaml  |   5 +-
 .../resources/conf/import/config-sharding.yaml     |   5 +-
 13 files changed, 186 insertions(+), 159 deletions(-)

diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdater.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdater.java
index 2212f724826..7ca32ce2d47 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdater.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdater.java
@@ -22,7 +22,7 @@ import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.ImportDa
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.proxy.backend.config.yaml.YamlProxyDatabaseConfiguration;
 import org.apache.shardingsphere.proxy.backend.exception.FileIOException;
-import org.apache.shardingsphere.proxy.backend.util.ImportUtils;
+import org.apache.shardingsphere.proxy.backend.util.YamlDatabaseConfigurationImportExecutor;
 
 import java.io.File;
 import java.io.IOException;
@@ -33,6 +33,8 @@ import java.sql.SQLException;
  */
 public final class ImportDatabaseConfigurationUpdater implements RALUpdater<ImportDatabaseConfigurationStatement> {
     
+    private final YamlDatabaseConfigurationImportExecutor databaseConfigImportExecutor = new YamlDatabaseConfigurationImportExecutor();
+    
     @Override
     public void executeUpdate(final String databaseName, final ImportDatabaseConfigurationStatement sqlStatement) throws SQLException {
         File file = new File(sqlStatement.getFilePath());
@@ -42,7 +44,7 @@ public final class ImportDatabaseConfigurationUpdater implements RALUpdater<Impo
         } catch (final IOException ex) {
             throw new FileIOException(ex);
         }
-        ImportUtils.importDatabaseConfig(yamlConfig);
+        databaseConfigImportExecutor.importDatabaseConfiguration(yamlConfig);
     }
     
     @Override
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataUpdater.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataUpdater.java
index d3e5b531f38..9e8a2f7e24d 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataUpdater.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataUpdater.java
@@ -29,8 +29,8 @@ import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedClusterInfo;
 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedMetaData;
 import org.apache.shardingsphere.proxy.backend.exception.FileIOException;
-import org.apache.shardingsphere.proxy.backend.util.ImportUtils;
 import org.apache.shardingsphere.proxy.backend.util.JsonUtils;
+import org.apache.shardingsphere.proxy.backend.util.YamlDatabaseConfigurationImportExecutor;
 
 import java.io.File;
 import java.io.IOException;
@@ -46,6 +46,8 @@ public final class ImportMetaDataUpdater implements RALUpdater<ImportMetaDataSta
     
     private final YamlRuleConfigurationSwapperEngine ruleConfigSwapperEngine = new YamlRuleConfigurationSwapperEngine();
     
+    private final YamlDatabaseConfigurationImportExecutor databaseConfigImportExecutor = new YamlDatabaseConfigurationImportExecutor();
+    
     @Override
     public void executeUpdate(final String databaseName, final ImportMetaDataStatement sqlStatement) throws SQLException {
         String jsonMetaDataConfig;
@@ -78,7 +80,7 @@ public final class ImportMetaDataUpdater implements RALUpdater<ImportMetaDataSta
     private void importDatabase(final ExportedMetaData exportedMetaData) {
         for (final String each : exportedMetaData.getDatabases().values()) {
             YamlProxyDatabaseConfiguration yamlDatabaseConfig = YamlEngine.unmarshal(each, YamlProxyDatabaseConfiguration.class);
-            ImportUtils.importDatabaseConfig(yamlDatabaseConfig);
+            databaseConfigImportExecutor.importDatabaseConfiguration(yamlDatabaseConfig);
         }
     }
     
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/ImportUtils.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
similarity index 77%
rename from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/ImportUtils.java
rename to proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
index c8321ac356c..cfc2845f398 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/ImportUtils.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
@@ -19,8 +19,6 @@ package org.apache.shardingsphere.proxy.backend.util;
 
 import com.google.common.base.Preconditions;
 import com.zaxxer.hikari.HikariDataSource;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.dbdiscovery.api.config.DatabaseDiscoveryRuleConfiguration;
 import org.apache.shardingsphere.dbdiscovery.rule.DatabaseDiscoveryRule;
 import org.apache.shardingsphere.dbdiscovery.yaml.config.YamlDatabaseDiscoveryRuleConfiguration;
@@ -81,70 +79,69 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 /**
- * Import utility class.
+ * Yaml database configuration import executor.
  */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ImportUtils {
+public final class YamlDatabaseConfigurationImportExecutor {
     
-    private static final ShardingRuleConfigurationImportChecker SHARDING_RULE_CONFIGURATION_IMPORT_CHECKER = new ShardingRuleConfigurationImportChecker();
+    private final ShardingRuleConfigurationImportChecker shardingRuleConfigImportChecker = new ShardingRuleConfigurationImportChecker();
     
-    private static final ReadwriteSplittingRuleConfigurationImportChecker READWRITE_SPLITTING_RULE_CONFIGURATION_IMPORT_CHECKER = new ReadwriteSplittingRuleConfigurationImportChecker();
+    private final ReadwriteSplittingRuleConfigurationImportChecker readwriteSplittingRuleConfigImportChecker = new ReadwriteSplittingRuleConfigurationImportChecker();
     
-    private static final DatabaseDiscoveryRuleConfigurationImportChecker DATABASE_DISCOVERY_RULE_CONFIGURATION_IMPORT_CHECKER = new DatabaseDiscoveryRuleConfigurationImportChecker();
+    private final DatabaseDiscoveryRuleConfigurationImportChecker databaseDiscoveryRuleConfigImportChecker = new DatabaseDiscoveryRuleConfigurationImportChecker();
     
-    private static final EncryptRuleConfigurationImportChecker ENCRYPT_RULE_CONFIGURATION_IMPORT_CHECKER = new EncryptRuleConfigurationImportChecker();
+    private final EncryptRuleConfigurationImportChecker encryptRuleConfigImportChecker = new EncryptRuleConfigurationImportChecker();
     
-    private static final ShadowRuleConfigurationImportChecker SHADOW_RULE_CONFIGURATION_IMPORT_CHECKER = new ShadowRuleConfigurationImportChecker();
+    private final ShadowRuleConfigurationImportChecker shadowRuleConfigImportChecker = new ShadowRuleConfigurationImportChecker();
     
-    private static final MaskRuleConfigurationImportChecker MASK_RULE_CONFIGURATION_IMPORT_CHECKER = new MaskRuleConfigurationImportChecker();
+    private final MaskRuleConfigurationImportChecker maskRuleConfigImportChecker = new MaskRuleConfigurationImportChecker();
     
-    private static final YamlProxyDataSourceConfigurationSwapper DATA_SOURCE_CONFIGURATION_SWAPPER = new YamlProxyDataSourceConfigurationSwapper();
+    private final YamlProxyDataSourceConfigurationSwapper dataSourceConfigSwapper = new YamlProxyDataSourceConfigurationSwapper();
     
-    private static final DataSourcePropertiesValidateHandler VALIDATE_HANDLER = new DataSourcePropertiesValidateHandler();
+    private final DataSourcePropertiesValidateHandler validateHandler = new DataSourcePropertiesValidateHandler();
     
     /**
      * Import proxy database from yaml configuration.
-     * 
+     *
      * @param yamlConfig yaml proxy database configuration
      */
-    public static void importDatabaseConfig(final YamlProxyDatabaseConfiguration yamlConfig) {
-        String yamlDatabaseName = yamlConfig.getDatabaseName();
-        checkDatabase(yamlDatabaseName);
+    public void importDatabaseConfiguration(final YamlProxyDatabaseConfiguration yamlConfig) {
+        String databaseName = yamlConfig.getDatabaseName();
+        checkDatabase(databaseName);
         checkDataSource(yamlConfig.getDataSources());
-        addDatabase(yamlDatabaseName);
-        addResources(yamlDatabaseName, yamlConfig.getDataSources());
+        addDatabase(databaseName);
+        addResources(databaseName, yamlConfig.getDataSources());
         try {
-            addRules(yamlDatabaseName, yamlConfig.getRules());
+            addRules(databaseName, yamlConfig.getRules());
         } catch (final DistSQLException ex) {
-            dropDatabase(yamlDatabaseName);
+            dropDatabase(databaseName);
             throw ex;
         }
     }
     
-    private static void checkDatabase(final String databaseName) {
+    private void checkDatabase(final String databaseName) {
         Preconditions.checkNotNull(databaseName, "Property `databaseName` in imported config is required");
         if (ProxyContext.getInstance().databaseExists(databaseName)) {
             Preconditions.checkState(ProxyContext.getInstance().getDatabase(databaseName).getResourceMetaData().getDataSources().isEmpty(), "Database `%s` exists and is not empty", databaseName);
         }
     }
     
-    private static void checkDataSource(final Map<String, YamlProxyDataSourceConfiguration> dataSources) {
+    private void checkDataSource(final Map<String, YamlProxyDataSourceConfiguration> dataSources) {
         Preconditions.checkState(!dataSources.isEmpty(), "Data source configurations in imported config is required");
     }
     
-    private static void addDatabase(final String databaseName) {
+    private void addDatabase(final String databaseName) {
         ContextManager contextManager = ProxyContext.getInstance().getContextManager();
         contextManager.getInstanceContext().getModeContextManager().createDatabase(databaseName);
         DatabaseType protocolType = DatabaseTypeEngine.getProtocolType(Collections.emptyMap(), contextManager.getMetaDataContexts().getMetaData().getProps());
         contextManager.getMetaDataContexts().getMetaData().addDatabase(databaseName, protocolType);
     }
     
-    private static void addResources(final String databaseName, final Map<String, YamlProxyDataSourceConfiguration> yamlDataSourceMap) {
+    private void addResources(final String databaseName, final Map<String, YamlProxyDataSourceConfiguration> yamlDataSourceMap) {
         Map<String, DataSourceProperties> dataSourcePropsMap = new LinkedHashMap<>(yamlDataSourceMap.size(), 1);
         for (Entry<String, YamlProxyDataSourceConfiguration> entry : yamlDataSourceMap.entrySet()) {
-            dataSourcePropsMap.put(entry.getKey(), DataSourcePropertiesCreator.create(HikariDataSource.class.getName(), DATA_SOURCE_CONFIGURATION_SWAPPER.swap(entry.getValue())));
+            dataSourcePropsMap.put(entry.getKey(), DataSourcePropertiesCreator.create(HikariDataSource.class.getName(), dataSourceConfigSwapper.swap(entry.getValue())));
         }
-        VALIDATE_HANDLER.validate(dataSourcePropsMap);
+        validateHandler.validate(dataSourcePropsMap);
         try {
             ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().registerStorageUnits(databaseName, dataSourcePropsMap);
         } catch (final SQLException ex) {
@@ -154,7 +151,7 @@ public class ImportUtils {
         dataSourcePropsMap.forEach((key, value) -> dataSource.put(key, DataSourcePoolCreator.create(value)));
     }
     
-    private static void addRules(final String databaseName, final Collection<YamlRuleConfiguration> yamlRuleConfigs) {
+    private void addRules(final String databaseName, final Collection<YamlRuleConfiguration> yamlRuleConfigs) {
         if (yamlRuleConfigs == null || yamlRuleConfigs.isEmpty()) {
             return;
         }
@@ -166,32 +163,32 @@ public class ImportUtils {
         for (YamlRuleConfiguration each : yamlRuleConfigs) {
             if (each instanceof YamlShardingRuleConfiguration) {
                 ShardingRuleConfiguration shardingRuleConfig = new YamlShardingRuleConfigurationSwapper().swapToObject((YamlShardingRuleConfiguration) each);
-                SHARDING_RULE_CONFIGURATION_IMPORT_CHECKER.check(database, shardingRuleConfig);
+                shardingRuleConfigImportChecker.check(database, shardingRuleConfig);
                 ruleConfigs.add(shardingRuleConfig);
                 rules.add(new ShardingRule(shardingRuleConfig, database.getResourceMetaData().getDataSources().keySet(), instanceContext));
             } else if (each instanceof YamlReadwriteSplittingRuleConfiguration) {
                 ReadwriteSplittingRuleConfiguration readwriteSplittingRuleConfig = new YamlReadwriteSplittingRuleConfigurationSwapper().swapToObject((YamlReadwriteSplittingRuleConfiguration) each);
-                READWRITE_SPLITTING_RULE_CONFIGURATION_IMPORT_CHECKER.check(database, readwriteSplittingRuleConfig);
+                readwriteSplittingRuleConfigImportChecker.check(database, readwriteSplittingRuleConfig);
                 ruleConfigs.add(readwriteSplittingRuleConfig);
                 rules.add(new ReadwriteSplittingRule(databaseName, readwriteSplittingRuleConfig, rules, instanceContext));
             } else if (each instanceof YamlDatabaseDiscoveryRuleConfiguration) {
                 DatabaseDiscoveryRuleConfiguration databaseDiscoveryRuleConfig = new YamlDatabaseDiscoveryRuleConfigurationSwapper().swapToObject((YamlDatabaseDiscoveryRuleConfiguration) each);
-                DATABASE_DISCOVERY_RULE_CONFIGURATION_IMPORT_CHECKER.check(database, databaseDiscoveryRuleConfig);
+                databaseDiscoveryRuleConfigImportChecker.check(database, databaseDiscoveryRuleConfig);
                 ruleConfigs.add(databaseDiscoveryRuleConfig);
                 rules.add(new DatabaseDiscoveryRule(databaseName, database.getResourceMetaData().getDataSources(), databaseDiscoveryRuleConfig, instanceContext));
             } else if (each instanceof YamlEncryptRuleConfiguration) {
                 EncryptRuleConfiguration encryptRuleConfig = new YamlEncryptRuleConfigurationSwapper().swapToObject((YamlEncryptRuleConfiguration) each);
-                ENCRYPT_RULE_CONFIGURATION_IMPORT_CHECKER.check(database, encryptRuleConfig);
+                encryptRuleConfigImportChecker.check(database, encryptRuleConfig);
                 ruleConfigs.add(encryptRuleConfig);
                 rules.add(new EncryptRule(encryptRuleConfig));
             } else if (each instanceof YamlShadowRuleConfiguration) {
                 ShadowRuleConfiguration shadowRuleConfig = new YamlShadowRuleConfigurationSwapper().swapToObject((YamlShadowRuleConfiguration) each);
-                SHADOW_RULE_CONFIGURATION_IMPORT_CHECKER.check(database, shadowRuleConfig);
+                shadowRuleConfigImportChecker.check(database, shadowRuleConfig);
                 ruleConfigs.add(shadowRuleConfig);
                 rules.add(new ShadowRule(shadowRuleConfig));
             } else if (each instanceof YamlMaskRuleConfiguration) {
                 MaskRuleConfiguration maskRuleConfig = new YamlMaskRuleConfigurationSwapper().swapToObject((YamlMaskRuleConfiguration) each);
-                MASK_RULE_CONFIGURATION_IMPORT_CHECKER.check(database, maskRuleConfig);
+                maskRuleConfigImportChecker.check(database, maskRuleConfig);
                 ruleConfigs.add(maskRuleConfig);
                 rules.add(new MaskRule(maskRuleConfig));
             }
@@ -199,7 +196,7 @@ public class ImportUtils {
         metaDataContexts.getPersistService().getDatabaseRulePersistService().persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), ruleConfigs);
     }
     
-    private static void dropDatabase(final String databaseName) {
+    private void dropDatabase(final String databaseName) {
         ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().dropDatabase(databaseName);
     }
 }
diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdaterTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdaterTest.java
index eef28a63a41..edfdb2a0ede 100644
--- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdaterTest.java
+++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationUpdaterTest.java
@@ -17,29 +17,30 @@
 
 package org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable;
 
+import lombok.SneakyThrows;
+import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
+import org.apache.shardingsphere.distsql.handler.validate.DataSourcePropertiesValidateHandler;
 import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.ImportDatabaseConfigurationStatement;
+import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
 import org.apache.shardingsphere.infra.database.DefaultDatabase;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
-import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
+import org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedRule;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
-import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource;
+import org.apache.shardingsphere.proxy.backend.util.YamlDatabaseConfigurationImportExecutor;
 import org.apache.shardingsphere.test.mock.AutoMockExtension;
 import org.apache.shardingsphere.test.mock.StaticMockSettings;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.internal.configuration.plugins.Plugins;
 
-import javax.sql.DataSource;
-import java.util.Collection;
+import java.sql.SQLException;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.util.Properties;
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -50,101 +51,123 @@ import static org.mockito.Mockito.when;
 @StaticMockSettings(ProxyContext.class)
 public final class ImportDatabaseConfigurationUpdaterTest {
     
-    private final String sharding = "sharding_db";
+    private ImportDatabaseConfigurationUpdater importDatabaseConfigUpdater;
     
-    private final String readwriteSplitting = "readwrite_splitting_db";
-    
-    private final String databaseDiscovery = "database_discovery_db";
-    
-    private final String encrypt = "encrypt_db";
-    
-    private final String shadow = "shadow_db";
+    @Test
+    public void assertImportDatabaseExecutorForSharding() throws SQLException {
+        String databaseName = "sharding_db";
+        init(databaseName);
+        importDatabaseConfigUpdater.executeUpdate(databaseName, new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-sharding.yaml")));
+    }
     
-    private final String mask = "mask_db";
+    @Test
+    public void assertImportDatabaseExecutorForReadwriteSplitting() throws SQLException {
+        String databaseName = "readwrite_splitting_db";
+        init(databaseName);
+        importDatabaseConfigUpdater.executeUpdate(databaseName, new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-readwrite-splitting.yaml")));
+    }
     
-    private ImportDatabaseConfigurationUpdater importDatabaseConfigurationUpdater;
+    @Test
+    public void assertImportDatabaseExecutorForDatabaseDiscovery() throws SQLException {
+        String databaseName = "database_discovery_db";
+        init(databaseName);
+        importDatabaseConfigUpdater.executeUpdate(databaseName, new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-database-discovery.yaml")));
+    }
     
-    private final Map<String, String> featureMap = new HashMap<>(3, 1);
+    @Test
+    public void assertImportDatabaseExecutorForEncrypt() throws SQLException {
+        String databaseName = "encrypt_db";
+        init(databaseName);
+        importDatabaseConfigUpdater.executeUpdate(databaseName, new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-encrypt.yaml")));
+    }
     
-    @BeforeEach
-    public void setup() {
-        featureMap.put(sharding, "/conf/import/config-sharding.yaml");
-        featureMap.put(readwriteSplitting, "/conf/import/config-readwrite-splitting.yaml");
-        featureMap.put(databaseDiscovery, "/conf/import/config-database-discovery.yaml");
-        featureMap.put(encrypt, "/conf/import/config-encrypt.yaml");
-        featureMap.put(shadow, "/conf/import/config-shadow.yaml");
-        featureMap.put(mask, "/conf/import/config-mask.yaml");
+    @Test
+    public void assertImportDatabaseExecutorForShadow() throws SQLException {
+        String databaseName = "shadow_db";
+        init(databaseName);
+        importDatabaseConfigUpdater.executeUpdate(databaseName, new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-shadow.yaml")));
     }
     
     @Test
-    public void assertImportDatabaseExecutorForSharding() {
-        init(sharding);
-        assertThrows(IllegalStateException.class, () -> importDatabaseConfigurationUpdater.executeUpdate(sharding,
-                new ImportDatabaseConfigurationStatement(Objects.requireNonNull(ImportDatabaseConfigurationUpdaterTest.class.getResource(featureMap.get(sharding))).getPath())));
+    public void assertImportDatabaseExecutorForMask() throws SQLException {
+        String databaseName = "mask_db";
+        init(databaseName);
+        importDatabaseConfigUpdater.executeUpdate(databaseName, new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-mask.yaml")));
     }
     
     @Test
-    public void assertImportDatabaseExecutorForReadwriteSplitting() {
-        init(readwriteSplitting);
-        assertThrows(IllegalStateException.class, () -> importDatabaseConfigurationUpdater.executeUpdate(readwriteSplitting,
-                new ImportDatabaseConfigurationStatement(Objects.requireNonNull(ImportDatabaseConfigurationUpdaterTest.class.getResource(featureMap.get(readwriteSplitting))).getPath())));
+    public void assertImportExistedDatabase() {
+        String databaseName = "sharding_db";
+        init(databaseName);
+        when(ProxyContext.getInstance().databaseExists(databaseName)).thenReturn(true);
+        assertThrows(IllegalStateException.class, () -> importDatabaseConfigUpdater.executeUpdate(databaseName,
+                new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-sharding.yaml"))));
     }
     
     @Test
-    public void assertImportDatabaseExecutorForDatabaseDiscovery() {
-        init(databaseDiscovery);
-        assertThrows(IllegalStateException.class, () -> importDatabaseConfigurationUpdater.executeUpdate(databaseDiscovery,
-                new ImportDatabaseConfigurationStatement(Objects.requireNonNull(ImportDatabaseConfigurationUpdaterTest.class.getResource(featureMap.get(databaseDiscovery))).getPath())));
+    public void assertImportEmptyDatabaseName() {
+        String databaseName = "sharding_db";
+        init(databaseName);
+        assertThrows(NullPointerException.class, () -> importDatabaseConfigUpdater.executeUpdate(databaseName,
+                new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-empty-database-name.yaml"))));
     }
     
     @Test
-    public void assertImportDatabaseExecutorForEncrypt() {
-        init(encrypt);
-        assertThrows(IllegalStateException.class, () -> importDatabaseConfigurationUpdater.executeUpdate(encrypt,
-                new ImportDatabaseConfigurationStatement(Objects.requireNonNull(ImportDatabaseConfigurationUpdaterTest.class.getResource(featureMap.get(encrypt))).getPath())));
+    public void assertImportEmptyDataSource() {
+        String databaseName = "sharding_db";
+        init(databaseName);
+        assertThrows(IllegalStateException.class, () -> importDatabaseConfigUpdater.executeUpdate(databaseName,
+                new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-empty-data-source.yaml"))));
     }
     
     @Test
-    public void assertImportDatabaseExecutorForShadow() {
-        init(shadow);
-        assertThrows(IllegalStateException.class, () -> importDatabaseConfigurationUpdater.executeUpdate(shadow,
-                new ImportDatabaseConfigurationStatement(Objects.requireNonNull(ImportDatabaseConfigurationUpdaterTest.class.getResource(featureMap.get(shadow))).getPath())));
+    public void assertImportDuplicatedLogicTable() {
+        String databaseName = "sharding_db";
+        init(databaseName);
+        assertThrows(DuplicateRuleException.class, () -> importDatabaseConfigUpdater.executeUpdate(databaseName,
+                new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-duplicated-logic-table.yaml"))));
     }
     
     @Test
-    public void assertImportDatabaseExecutorForMask() {
-        init(mask);
-        assertThrows(IllegalStateException.class, () -> importDatabaseConfigurationUpdater.executeUpdate(mask,
-                new ImportDatabaseConfigurationStatement(Objects.requireNonNull(ImportDatabaseConfigurationUpdaterTest.class.getResource(featureMap.get(mask))).getPath())));
+    public void assertImportInvalidAlgorithm() {
+        String databaseName = "sharding_db";
+        init(databaseName);
+        assertThrows(InvalidAlgorithmConfigurationException.class, () -> importDatabaseConfigUpdater.executeUpdate(databaseName,
+                new ImportDatabaseConfigurationStatement(getDatabaseConfigurationFilePath("/conf/import/config-invalid-algorithm.yaml"))));
     }
     
-    private void init(final String feature) {
-        importDatabaseConfigurationUpdater = new ImportDatabaseConfigurationUpdater();
-        ContextManager contextManager = mockContextManager(feature);
+    @SneakyThrows({IllegalAccessException.class, NoSuchFieldException.class})
+    private void init(final String databaseName) {
+        ContextManager contextManager = mockContextManager(databaseName);
         when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
-        when(ProxyContext.getInstance().databaseExists(feature)).thenReturn(true);
+        importDatabaseConfigUpdater = new ImportDatabaseConfigurationUpdater();
+        YamlDatabaseConfigurationImportExecutor databaseConfigImportExecutor = new YamlDatabaseConfigurationImportExecutor();
+        Plugins.getMemberAccessor().set(importDatabaseConfigUpdater.getClass().getDeclaredField("databaseConfigImportExecutor"), importDatabaseConfigUpdater, databaseConfigImportExecutor);
+        Plugins.getMemberAccessor().set(databaseConfigImportExecutor.getClass().getDeclaredField("validateHandler"), databaseConfigImportExecutor, mock(DataSourcePropertiesValidateHandler.class));
     }
     
-    private ContextManager mockContextManager(final String feature) {
+    private ContextManager mockContextManager(final String databaseName) {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
-        when(database.getSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(new ShardingSphereSchema(createTableMap(), Collections.emptyMap()));
-        when(database.getResourceMetaData().getDataSources()).thenReturn(createDataSourceMap());
-        when(result.getMetaDataContexts().getMetaData().getDatabases()).thenReturn(Collections.singletonMap(feature, database));
-        when(result.getMetaDataContexts().getMetaData().getDatabase(feature)).thenReturn(database);
+        ShardingSphereResourceMetaData resourceMetaData = mock(ShardingSphereResourceMetaData.class);
+        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
+        ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
+        when(database.getSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(schema);
+        DataSourceContainedRule dataSourceContainedRule = mock(DataSourceContainedRule.class);
+        when(database.getRuleMetaData().findRules(DataSourceContainedRule.class)).thenReturn(Collections.singleton(dataSourceContainedRule));
+        when(result.getMetaDataContexts().getMetaData().getDatabases()).thenReturn(Collections.singletonMap(databaseName, database));
+        when(result.getMetaDataContexts().getMetaData().getDatabase(databaseName)).thenReturn(database);
+        when(result.getMetaDataContexts().getMetaData().getProps()).thenReturn(new ConfigurationProperties(createProperties()));
         return result;
     }
     
-    private Map<String, DataSource> createDataSourceMap() {
-        Map<String, DataSource> result = new LinkedHashMap<>(2, 1);
-        result.put("ds_0", new MockedDataSource());
-        result.put("ds_1", new MockedDataSource());
+    private Properties createProperties() {
+        Properties result = new Properties();
+        result.setProperty(ConfigurationPropertyKey.PROXY_FRONTEND_DATABASE_PROTOCOL_TYPE.getKey(), "MySQL");
         return result;
     }
     
-    private Map<String, ShardingSphereTable> createTableMap() {
-        Collection<ShardingSphereColumn> columns = Collections.singleton(new ShardingSphereColumn("order_id", 0, false, false, false, true, false));
-        Collection<ShardingSphereIndex> indexes = Collections.singleton(new ShardingSphereIndex("primary"));
-        return Collections.singletonMap("t_order", new ShardingSphereTable("t_order", columns, indexes, Collections.emptyList()));
+    private String getDatabaseConfigurationFilePath(final String filePath) {
+        return ImportDatabaseConfigurationUpdaterTest.class.getResource(filePath).getPath();
     }
 }
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-database-discovery.yaml b/proxy/backend/core/src/test/resources/conf/import/config-database-discovery.yaml
index befecf2a4c3..1c0857a645d 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-database-discovery.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-database-discovery.yaml
@@ -62,6 +62,6 @@ rules:
         keep-alive-cron: '0/5 * * * * ?'
   discoveryTypes:
     mgr:
-      type: MGR
+      type: MySQL.MGR
       props:
         group-name: 92504d5b-6dec-11e8-91ea-246e9612aaf1
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml b/proxy/backend/core/src/test/resources/conf/import/config-duplicated-logic-table.yaml
similarity index 86%
copy from proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
copy to proxy/backend/core/src/test/resources/conf/import/config-duplicated-logic-table.yaml
index 05ec0068511..d69b1c4625a 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-duplicated-logic-table.yaml
@@ -18,7 +18,7 @@
 databaseName: sharding_db
 
 dataSources:
-  ds_1:
+  ds_0:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +27,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  ds_1:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -51,13 +51,23 @@ rules:
           keyGeneratorName: snowflake
       t_order_item:
         actualDataNodes: ds_${0..1}.t_order_item_${0..1}
-        tableStrategy:
+        tableStrategy: 
           standard:
             shardingColumn: order_id
             shardingAlgorithmName: t_order_item_inline
         keyGenerateStrategy:
           column: order_item_id
           keyGeneratorName: snowflake
+    autoTables:
+      t_order:
+        actualDataSources: ds_0,ds_1
+        shardingStrategy:
+          standard:
+            shardingColumn: order_id
+            shardingAlgorithmName: auto-mod
+        keyGenerateStrategy:
+          column: order_id
+          keyGeneratorName: snowflake
     bindingTables:
       - t_order,t_order_item
     defaultDatabaseStrategy:
@@ -80,8 +90,11 @@ rules:
         type: INLINE
         props:
           algorithm-expression: t_order_item_${order_id % 2}
+      auto-mod:
+        type: MOD
+        props:
+          sharding-count: 4
 
     keyGenerators:
       snowflake:
         type: SNOWFLAKE
-
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-empty-data-source.yaml b/proxy/backend/core/src/test/resources/conf/import/config-empty-data-source.yaml
new file mode 100644
index 00000000000..1b5e0296bdf
--- /dev/null
+++ b/proxy/backend/core/src/test/resources/conf/import/config-empty-data-source.yaml
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+databaseName: sharding_db
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml b/proxy/backend/core/src/test/resources/conf/import/config-empty-database-name.yaml
similarity index 73%
copy from proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml
copy to proxy/backend/core/src/test/resources/conf/import/config-empty-database-name.yaml
index 19df047b882..90fe05ebcf3 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-empty-database-name.yaml
@@ -15,10 +15,8 @@
 # limitations under the License.
 #
 
-databaseName: encrypt_db
-
 dataSources:
-  ds_1:
+  ds_0:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +25,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  ds_1:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -36,24 +34,3 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-
-rules:
-  - !ENCRYPT
-    encryptors:
-      aes_encryptor:
-        type: AES
-        props:
-          aes-key-value: 123456abc
-      md5_encryptor:
-        type: MD5
-    tables:
-      t_encrypt:
-        columns:
-          user_id:
-            plainColumn: user_plain
-            cipherColumn: user_cipher
-            encryptorName: aes_encryptor
-          order_id:
-            cipherColumn: order_cipher
-            encryptorName: md5_encryptor
-
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml b/proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml
index 19df047b882..9b084124163 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-encrypt.yaml
@@ -18,7 +18,7 @@
 databaseName: encrypt_db
 
 dataSources:
-  ds_1:
+  ds_0:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +27,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  ds_1:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -56,4 +56,3 @@ rules:
           order_id:
             cipherColumn: order_cipher
             encryptorName: md5_encryptor
-
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml b/proxy/backend/core/src/test/resources/conf/import/config-invalid-algorithm.yaml
similarity index 95%
copy from proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
copy to proxy/backend/core/src/test/resources/conf/import/config-invalid-algorithm.yaml
index 05ec0068511..18f7c5f0581 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-invalid-algorithm.yaml
@@ -18,7 +18,7 @@
 databaseName: sharding_db
 
 dataSources:
-  ds_1:
+  ds_0:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +27,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  ds_1:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -69,19 +69,18 @@ rules:
 
     shardingAlgorithms:
       database_inline:
-        type: INLINE
+        type: INLINE_ERROR
         props:
           algorithm-expression: ds_${user_id % 2}
       t_order_inline:
-        type: INLINE
+        type: INLINE_ERROR
         props:
           algorithm-expression: t_order_${order_id % 2}
       t_order_item_inline:
-        type: INLINE
+        type: INLINE_ERROR
         props:
           algorithm-expression: t_order_item_${order_id % 2}
 
     keyGenerators:
       snowflake:
-        type: SNOWFLAKE
-
+        type: SNOWFLAKE_ERROR
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-mask.yaml b/proxy/backend/core/src/test/resources/conf/import/config-mask.yaml
index 1bdf594a1c1..3c9986f6712 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-mask.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-mask.yaml
@@ -18,7 +18,7 @@
 databaseName: mask_db
 
 dataSources:
-  ds_1:
+  ds_0:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +27,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  ds_1:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -63,4 +63,3 @@ rules:
           first-n: 3
           last-m: 4
           replace-char: '*'
-
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-shadow.yaml b/proxy/backend/core/src/test/resources/conf/import/config-shadow.yaml
index 203a2128439..19e94dca277 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-shadow.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-shadow.yaml
@@ -18,7 +18,7 @@
 databaseName: shadow_db
 
 dataSources:
-  ds_1:
+  ds:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +27,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  shadow_ds:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -87,4 +87,3 @@ rules:
         type: SQL_HINT
         props:
           foo: bar
-
diff --git a/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml b/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
index 05ec0068511..f195f58ce36 100644
--- a/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
+++ b/proxy/backend/core/src/test/resources/conf/import/config-sharding.yaml
@@ -18,7 +18,7 @@
 databaseName: sharding_db
 
 dataSources:
-  ds_1:
+  ds_0:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -27,7 +27,7 @@ dataSources:
     maxLifetimeMilliseconds: 1800000
     maxPoolSize: 50
     minPoolSize: 1
-  ds_2:
+  ds_1:
     url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
     username: root
     password:
@@ -84,4 +84,3 @@ rules:
     keyGenerators:
       snowflake:
         type: SNOWFLAKE
-