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 2022/04/11 08:05:46 UTC

[shardingsphere] branch master updated: Add more validation for import schema config. (#16719)

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 a1dd2b6369b Add more validation for import schema config. (#16719)
a1dd2b6369b is described below

commit a1dd2b6369bbe69242ae18c239b8d964bfd17e5d
Author: yx9o <ya...@163.com>
AuthorDate: Mon Apr 11 16:05:40 2022 +0800

    Add more validation for import schema config. (#16719)
    
    * Add more validation for import schema config.
    
    * Update.
---
 ...reateDatabaseDiscoveryRuleStatementUpdater.java | 13 ++--
 ...aseDiscoveryRuleConfigurationImportChecker.java | 84 ++++++++++++++++++++++
 .../common/exception/CommonDistSQLException.java   |  1 +
 .../ImportSchemaConfigurationHandler.java          | 17 +++--
 .../ImportSchemaConfigurationHandlerTest.java      | 49 +++++++++----
 .../conf/import/config-database-discovery.yaml     | 67 +++++++++++++++++
 6 files changed, 203 insertions(+), 28 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-handler/src/main/java/org/apache/shardingsphere/dbdiscovery/distsql/handler/update/CreateDatabaseDiscoveryRuleStatementUpdater.java b/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-handler/src/main/java/org/apache/shardingsphere/dbdiscovery/distsql/handler/update/CreateDatabaseD [...]
index deadbff79f7..8ad396176ba 100644
--- a/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-handler/src/main/java/org/apache/shardingsphere/dbdiscovery/distsql/handler/update/CreateDatabaseDiscoveryRuleStatementUpdater.java
+++ b/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-handler/src/main/java/org/apache/shardingsphere/dbdiscovery/distsql/handler/update/CreateDatabaseDiscoveryRuleStatementUpdater.java
@@ -50,7 +50,7 @@ import java.util.stream.Collectors;
  */
 public final class CreateDatabaseDiscoveryRuleStatementUpdater implements RuleDefinitionCreateUpdater<CreateDatabaseDiscoveryRuleStatement, DatabaseDiscoveryRuleConfiguration> {
     
-    private static final String RULE_TYPE = "database discovery";
+    private static final String RULE_TYPE = "Database discovery";
     
     static {
         // TODO consider about register once only
@@ -63,7 +63,7 @@ public final class CreateDatabaseDiscoveryRuleStatementUpdater implements RuleDe
         String schemaName = shardingSphereMetaData.getName();
         checkDuplicateRuleNames(schemaName, sqlStatement, currentRuleConfig);
         checkResources(schemaName, sqlStatement, shardingSphereMetaData.getResource());
-        checkDiscoverTypeAndHeartbeat(sqlStatement, currentRuleConfig);
+        checkDiscoverTypeAndHeartbeat(schemaName, sqlStatement, currentRuleConfig);
     }
     
     private void checkDuplicateRuleNames(final String schemaName, final CreateDatabaseDiscoveryRuleStatement sqlStatement,
@@ -74,7 +74,7 @@ public final class CreateDatabaseDiscoveryRuleStatementUpdater implements RuleDe
         Collection<String> existRuleNames = currentRuleConfig.getDataSources().stream().map(DatabaseDiscoveryDataSourceRuleConfiguration::getGroupName).collect(Collectors.toList());
         Collection<String> duplicateRuleNames = sqlStatement.getRules().stream().map(AbstractDatabaseDiscoverySegment::getName).filter(existRuleNames::contains).collect(Collectors.toSet());
         duplicateRuleNames.addAll(getToBeCreatedDuplicateRuleNames(sqlStatement));
-        DistSQLException.predictionThrow(duplicateRuleNames.isEmpty(), () -> new DuplicateRuleException(RULE_TYPE, schemaName, duplicateRuleNames));
+        DistSQLException.predictionThrow(duplicateRuleNames.isEmpty(), () -> new DuplicateRuleException(RULE_TYPE.toLowerCase(), schemaName, duplicateRuleNames));
     }
     
     private Collection<String> getToBeCreatedDuplicateRuleNames(final CreateDatabaseDiscoveryRuleStatement sqlStatement) {
@@ -92,12 +92,13 @@ public final class CreateDatabaseDiscoveryRuleStatementUpdater implements RuleDe
         }
     }
     
-    private void checkDiscoverTypeAndHeartbeat(final CreateDatabaseDiscoveryRuleStatement sqlStatement, final DatabaseDiscoveryRuleConfiguration currentRuleConfig) throws DistSQLException {
+    private void checkDiscoverTypeAndHeartbeat(final String schemaName, final CreateDatabaseDiscoveryRuleStatement sqlStatement,
+                                               final DatabaseDiscoveryRuleConfiguration currentRuleConfig) throws DistSQLException {
         Map<String, List<AbstractDatabaseDiscoverySegment>> segmentMap = sqlStatement.getRules().stream().collect(Collectors.groupingBy(each -> each.getClass().getSimpleName()));
         Collection<String> invalidInput = segmentMap.getOrDefault(DatabaseDiscoveryDefinitionSegment.class.getSimpleName(), Collections.emptyList()).stream()
                 .map(each -> ((DatabaseDiscoveryDefinitionSegment) each).getDiscoveryType().getName()).distinct()
                 .filter(each -> !TypedSPIRegistry.findRegisteredService(DatabaseDiscoveryType.class, each, new Properties()).isPresent()).collect(Collectors.toList());
-        DistSQLException.predictionThrow(invalidInput.isEmpty(), () -> new InvalidAlgorithmConfigurationException(RULE_TYPE, invalidInput));
+        DistSQLException.predictionThrow(invalidInput.isEmpty(), () -> new InvalidAlgorithmConfigurationException(RULE_TYPE.toLowerCase(), invalidInput));
         segmentMap.getOrDefault(DatabaseDiscoveryConstructionSegment.class.getSimpleName(), Collections.emptyList()).stream().map(each -> (DatabaseDiscoveryConstructionSegment) each)
                 .forEach(each -> {
                     if (null == currentRuleConfig || !currentRuleConfig.getDiscoveryTypes().containsKey(each.getDiscoveryTypeName())) {
@@ -107,7 +108,7 @@ public final class CreateDatabaseDiscoveryRuleStatementUpdater implements RuleDe
                         invalidInput.add(each.getDiscoveryHeartbeatName());
                     }
                 });
-        DistSQLException.predictionThrow(invalidInput.isEmpty(), () -> new RequiredAlgorithmMissedException(RULE_TYPE, invalidInput));
+        DistSQLException.predictionThrow(invalidInput.isEmpty(), () -> new RequiredAlgorithmMissedException(RULE_TYPE, schemaName, invalidInput));
     }
     
     @Override
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/checker/DatabaseDiscoveryRuleConfigurationImportChecker.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/checker/DatabaseDiscoveryRuleConfigurationImportChecker.java
new file mode 100644
index 00000000000..1a1e791ce4f
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/checker/DatabaseDiscoveryRuleConfigurationImportChecker.java
@@ -0,0 +1,84 @@
+/*
+ * 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.proxy.backend.text.distsql.ral.common.checker;
+
+import org.apache.shardingsphere.dbdiscovery.api.config.DatabaseDiscoveryRuleConfiguration;
+import org.apache.shardingsphere.dbdiscovery.spi.DatabaseDiscoveryType;
+import org.apache.shardingsphere.infra.config.TypedSPIConfiguration;
+import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
+import org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
+import org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
+import org.apache.shardingsphere.infra.distsql.exception.rule.RequiredAlgorithmMissedException;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.spi.ShardingSphereServiceLoader;
+import org.apache.shardingsphere.spi.type.typed.TypedSPIRegistry;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+/**
+ * Database discovery rule configuration import checker.
+ */
+public final class DatabaseDiscoveryRuleConfigurationImportChecker {
+    
+    private static final String DB_DISCOVERY = "Database discovery";
+    
+    static {
+        ShardingSphereServiceLoader.register(DatabaseDiscoveryType.class);
+    }
+    
+    /**
+     * Check database discovery rule configuration.
+     *
+     * @param shardingSphereMetaData ShardingSphere meta data
+     * @param currentRuleConfig current rule configuration
+     * @throws DistSQLException definition violation exception
+     */
+    public void check(final ShardingSphereMetaData shardingSphereMetaData, final DatabaseDiscoveryRuleConfiguration currentRuleConfig) throws DistSQLException {
+        if (null == shardingSphereMetaData || null == currentRuleConfig) {
+            return;
+        }
+        String schemaName = shardingSphereMetaData.getName();
+        checkResources(schemaName, shardingSphereMetaData, currentRuleConfig);
+        checkDiscoverTypeAndHeartbeat(schemaName, currentRuleConfig);
+    }
+    
+    private void checkResources(final String schemaName, final ShardingSphereMetaData shardingSphereMetaData, final DatabaseDiscoveryRuleConfiguration currentRuleConfig) throws DistSQLException {
+        Collection<String> requireResources = new LinkedHashSet<>();
+        currentRuleConfig.getDataSources().forEach(each -> requireResources.addAll(each.getDataSourceNames()));
+        Collection<String> notExistResources = shardingSphereMetaData.getResource().getNotExistedResources(requireResources);
+        DistSQLException.predictionThrow(notExistResources.isEmpty(), () -> new RequiredResourceMissedException(schemaName, notExistResources));
+    }
+    
+    private void checkDiscoverTypeAndHeartbeat(final String schemaName, final DatabaseDiscoveryRuleConfiguration currentRuleConfig) throws DistSQLException {
+        Collection<String> invalidInput = currentRuleConfig.getDiscoveryTypes().values().stream().map(TypedSPIConfiguration::getType)
+                .filter(each -> !TypedSPIRegistry.findRegisteredService(DatabaseDiscoveryType.class, each, new Properties()).isPresent()).collect(Collectors.toList());
+        DistSQLException.predictionThrow(invalidInput.isEmpty(), () -> new InvalidAlgorithmConfigurationException(DB_DISCOVERY.toLowerCase(), invalidInput));
+        currentRuleConfig.getDataSources().stream().forEach(each -> {
+            if (!currentRuleConfig.getDiscoveryTypes().containsKey(each.getDiscoveryTypeName())) {
+                invalidInput.add(each.getDiscoveryTypeName());
+            }
+            if (!currentRuleConfig.getDiscoveryHeartbeats().containsKey(each.getDiscoveryHeartbeatName())) {
+                invalidInput.add(each.getDiscoveryHeartbeatName());
+            }
+        });
+        DistSQLException.predictionThrow(invalidInput.isEmpty(), () -> new RequiredAlgorithmMissedException(DB_DISCOVERY, schemaName, invalidInput));
+    }
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/exception/CommonDistSQLException.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/exception/CommonDistSQLException.java
index 1dc787e06ad..b664afc740f 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/exception/CommonDistSQLException.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/exception/CommonDistSQLException.java
@@ -26,6 +26,7 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 @Getter
 public class CommonDistSQLException extends RuntimeException {
+    
     private static final long serialVersionUID = 4207057904023183986L;
     
     private final String variable;
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandler.java
index 32144c8f223..3a2a541f1b7 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandler.java
@@ -47,6 +47,7 @@ import org.apache.shardingsphere.proxy.backend.config.yaml.YamlProxySchemaConfig
 import org.apache.shardingsphere.proxy.backend.config.yaml.swapper.YamlProxyDataSourceConfigurationSwapper;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.UpdatableRALBackendHandler;
+import org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.checker.DatabaseDiscoveryRuleConfigurationImportChecker;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.checker.ReadwriteSplittingRuleConfigurationImportChecker;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.checker.ShardingRuleConfigurationImportChecker;
 import org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
@@ -74,15 +75,17 @@ import java.util.stream.Collectors;
  * Import schema configuration handler.
  */
 public final class ImportSchemaConfigurationHandler extends UpdatableRALBackendHandler<ImportSchemaConfigurationStatement, ImportSchemaConfigurationHandler> {
-
+    
     private final DataSourcePropertiesValidator validator = new DataSourcePropertiesValidator();
-
+    
     private final ShardingRuleConfigurationImportChecker shardingRuleConfigurationImportChecker = new ShardingRuleConfigurationImportChecker();
     
     private final ReadwriteSplittingRuleConfigurationImportChecker readwriteSplittingRuleConfigurationImportChecker = new ReadwriteSplittingRuleConfigurationImportChecker();
     
+    private final DatabaseDiscoveryRuleConfigurationImportChecker databaseDiscoveryRuleConfigurationImportChecker = new DatabaseDiscoveryRuleConfigurationImportChecker();
+    
     private final YamlProxyDataSourceConfigurationSwapper dataSourceConfigSwapper = new YamlProxyDataSourceConfigurationSwapper();
-
+    
     private void alterResourcesConfig(final String schemaName, final Map<String, YamlProxyDataSourceConfiguration> yamlDataSourceMap) throws DistSQLException {
         Map<String, DataSourceProperties> toBeUpdatedResourcePropsMap = new LinkedHashMap<>(yamlDataSourceMap.size(), 1);
         for (Entry<String, YamlProxyDataSourceConfiguration> each : yamlDataSourceMap.entrySet()) {
@@ -102,7 +105,7 @@ public final class ImportSchemaConfigurationHandler extends UpdatableRALBackendH
             throw new InvalidResourcesException(toBeUpdatedResourcePropsMap.keySet());
         }
     }
-
+    
     private void alterRulesConfig(final String schemaName, final Collection<YamlRuleConfiguration> yamlRuleConfigurations) throws DistSQLException {
         if (null == yamlRuleConfigurations || yamlRuleConfigurations.isEmpty()) {
             return;
@@ -122,7 +125,7 @@ public final class ImportSchemaConfigurationHandler extends UpdatableRALBackendH
                 toBeUpdatedRuleConfigs.add(readwriteSplittingRuleConfiguration);
             } else if (each instanceof YamlDatabaseDiscoveryRuleConfiguration) {
                 DatabaseDiscoveryRuleConfiguration databaseDiscoveryRuleConfiguration = new DatabaseDiscoveryRuleConfigurationYamlSwapper().swapToObject((YamlDatabaseDiscoveryRuleConfiguration) each);
-                // TODO check
+                databaseDiscoveryRuleConfigurationImportChecker.check(shardingSphereMetaData, databaseDiscoveryRuleConfiguration);
                 toBeUpdatedRuleConfigs.add(databaseDiscoveryRuleConfiguration);
             } else if (each instanceof YamlEncryptRuleConfiguration) {
                 EncryptRuleConfiguration encryptRuleConfiguration = new EncryptRuleConfigurationYamlSwapper().swapToObject((YamlEncryptRuleConfiguration) each);
@@ -140,13 +143,13 @@ public final class ImportSchemaConfigurationHandler extends UpdatableRALBackendH
         Optional<MetaDataPersistService> metaDataPersistService = metaDataContexts.getMetaDataPersistService();
         metaDataPersistService.ifPresent(op -> op.getSchemaRuleService().persist(schemaName, toBeUpdatedRuleConfigs));
     }
-
+    
     private void checkSchemaName(final String schemaName) {
         if (!ProxyContext.getInstance().getAllSchemaNames().contains(schemaName)) {
             throw new SchemaNotExistedException(schemaName);
         }
     }
-
+    
     @Override
     protected void update(final ContextManager contextManager, final ImportSchemaConfigurationStatement sqlStatement) throws DistSQLException {
         if (!sqlStatement.getFilePath().isPresent()) {
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandlerTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandlerTest.java
index be213176357..5bb195bdbb5 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandlerTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/ImportSchemaConfigurationHandlerTest.java
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.updatable;
 
-import com.zaxxer.hikari.HikariDataSource;
 import org.apache.shardingsphere.distsql.parser.statement.ral.common.updatable.ImportSchemaConfigurationStatement;
 import org.apache.shardingsphere.infra.config.RuleConfiguration;
 import org.apache.shardingsphere.infra.datasource.props.DataSourcePropertiesValidator;
@@ -32,8 +31,10 @@ import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
 import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.RALBackendHandler;
+import org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.checker.DatabaseDiscoveryRuleConfigurationImportChecker;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.checker.ReadwriteSplittingRuleConfigurationImportChecker;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.checker.ShardingRuleConfigurationImportChecker;
+import org.apache.shardingsphere.test.mock.MockedDataSource;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,10 +64,14 @@ public final class ImportSchemaConfigurationHandlerTest {
     
     private final String readwriteSplittingFilePath = "/conf/import/config-readwrite-splitting.yaml";
     
+    private final String dbDiscoveryFilePath = "/conf/import/config-database-discovery.yaml";
+    
     private final String sharding = "sharding_db";
     
     private final String readwriteSplitting = "readwrite_splitting_db";
     
+    private final String databaseDiscovery = "database_discovery_db";
+    
     @Mock
     private DataSourcePropertiesValidator validator;
     
@@ -76,6 +81,9 @@ public final class ImportSchemaConfigurationHandlerTest {
     @Mock
     private ReadwriteSplittingRuleConfigurationImportChecker readwriteSplittingRuleConfigurationImportChecker;
     
+    @Mock
+    private DatabaseDiscoveryRuleConfigurationImportChecker databaseDiscoveryRuleConfigurationImportChecker;
+    
     private ImportSchemaConfigurationHandler importSchemaConfigurationHandler;
     
     private final Map<String, String> featureMap = new HashMap<>();
@@ -84,6 +92,7 @@ public final class ImportSchemaConfigurationHandlerTest {
     public void setup() {
         featureMap.put(sharding, shardingFilePath);
         featureMap.put(readwriteSplitting, readwriteSplittingFilePath);
+        featureMap.put(databaseDiscovery, dbDiscoveryFilePath);
     }
     
     private void init(final String feature) throws Exception {
@@ -103,9 +112,9 @@ public final class ImportSchemaConfigurationHandlerTest {
     @Test
     public void assertImportSchemaExecutorForSharding() throws Exception {
         init(sharding);
-        Field importCheckerForShardingRuleConfigurationField = importSchemaConfigurationHandler.getClass().getDeclaredField("shardingRuleConfigurationImportChecker");
-        importCheckerForShardingRuleConfigurationField.setAccessible(true);
-        importCheckerForShardingRuleConfigurationField.set(importSchemaConfigurationHandler, shardingRuleConfigurationImportChecker);
+        Field shardingRuleConfigurationImportCheckerField = importSchemaConfigurationHandler.getClass().getDeclaredField("shardingRuleConfigurationImportChecker");
+        shardingRuleConfigurationImportCheckerField.setAccessible(true);
+        shardingRuleConfigurationImportCheckerField.set(importSchemaConfigurationHandler, shardingRuleConfigurationImportChecker);
         Map<String, DataSource> dataSourceMap = ProxyContext.getInstance().getContextManager().getDataSourceMap(sharding);
         assertNotNull(dataSourceMap);
         Collection<RuleConfiguration> ruleConfigurations = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(sharding).getRuleMetaData().getConfigurations();
@@ -117,9 +126,9 @@ public final class ImportSchemaConfigurationHandlerTest {
     @Test
     public void assertImportSchemaExecutorForReadwriteSplitting() throws Exception {
         init(readwriteSplitting);
-        Field shardingRuleConfigurationCheckerField = importSchemaConfigurationHandler.getClass().getDeclaredField("readwriteSplittingRuleConfigurationImportChecker");
-        shardingRuleConfigurationCheckerField.setAccessible(true);
-        shardingRuleConfigurationCheckerField.set(importSchemaConfigurationHandler, readwriteSplittingRuleConfigurationImportChecker);
+        Field readwriteSplittingRuleConfigurationImportCheckerField = importSchemaConfigurationHandler.getClass().getDeclaredField("readwriteSplittingRuleConfigurationImportChecker");
+        readwriteSplittingRuleConfigurationImportCheckerField.setAccessible(true);
+        readwriteSplittingRuleConfigurationImportCheckerField.set(importSchemaConfigurationHandler, readwriteSplittingRuleConfigurationImportChecker);
         Map<String, DataSource> dataSourceMap = ProxyContext.getInstance().getContextManager().getDataSourceMap(readwriteSplitting);
         assertNotNull(dataSourceMap);
         Collection<RuleConfiguration> ruleConfigurations = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(readwriteSplitting).getRuleMetaData().getConfigurations();
@@ -128,19 +137,29 @@ public final class ImportSchemaConfigurationHandlerTest {
         assertTrue(responseHeader instanceof UpdateResponseHeader);
     }
     
+    @Test
+    public void assertImportSchemaExecutorForDatabaseDiscovery() throws Exception {
+        init(databaseDiscovery);
+        Field databaseDiscoveryRuleConfigurationImportCheckerField = importSchemaConfigurationHandler.getClass().getDeclaredField("databaseDiscoveryRuleConfigurationImportChecker");
+        databaseDiscoveryRuleConfigurationImportCheckerField.setAccessible(true);
+        databaseDiscoveryRuleConfigurationImportCheckerField.set(importSchemaConfigurationHandler, databaseDiscoveryRuleConfigurationImportChecker);
+        Map<String, DataSource> dataSourceMap = ProxyContext.getInstance().getContextManager().getDataSourceMap(databaseDiscovery);
+        assertNotNull(dataSourceMap);
+        Collection<RuleConfiguration> ruleConfigurations = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(databaseDiscovery).getRuleMetaData().getConfigurations();
+        assertNotNull(ruleConfigurations);
+        ResponseHeader responseHeader = importSchemaConfigurationHandler.execute();
+        assertTrue(responseHeader instanceof UpdateResponseHeader);
+    }
+    
     private Map<String, DataSource> createDataSourceMap() {
         Map<String, DataSource> result = new LinkedHashMap<>(2, 1);
-        result.put("ds_0", createDataSource("demo_ds_0"));
-        result.put("ds_1", createDataSource("demo_ds_1"));
+        result.put("ds_0", createDataSource());
+        result.put("ds_1", createDataSource());
         return result;
     }
     
-    private DataSource createDataSource(final String dbName) {
-        HikariDataSource result = new HikariDataSource();
-        result.setJdbcUrl(String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL", dbName));
-        result.setUsername("root");
-        result.setPassword("");
-        return result;
+    private DataSource createDataSource() {
+        return new MockedDataSource();
     }
     
     private Map<String, TableMetaData> createTableMap() {
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/resources/conf/import/config-database-discovery.yaml b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/resources/conf/import/config-database-discovery.yaml
new file mode 100644
index 00000000000..5ccdaeb60a9
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/resources/conf/import/config-database-discovery.yaml
@@ -0,0 +1,67 @@
+#
+# 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.
+#
+
+schemaName: database_discovery_db
+
+dataSources:
+  ds_0:
+    url: jdbc:mysql://127.0.0.1:3306/demo_primary_ds?serverTimezone=UTC&useSSL=false
+    username: root
+    password:
+    connectionTimeoutMilliseconds: 3000
+    idleTimeoutMilliseconds: 60000
+    maxLifetimeMilliseconds: 1800000
+    maxPoolSize: 50
+    minPoolSize: 1
+  ds_1:
+    url: jdbc:mysql://127.0.0.1:3306/demo_replica_ds_0?serverTimezone=UTC&useSSL=false
+    username: root
+    password:
+    connectionTimeoutMilliseconds: 3000
+    idleTimeoutMilliseconds: 60000
+    maxLifetimeMilliseconds: 1800000
+    maxPoolSize: 50
+    minPoolSize: 1
+  ds_2:
+    url: jdbc:mysql://127.0.0.1:3306/demo_replica_ds_1?serverTimezone=UTC&useSSL=false
+    username: root
+    password:
+    connectionTimeoutMilliseconds: 3000
+    idleTimeoutMilliseconds: 60000
+    maxLifetimeMilliseconds: 1800000
+    maxPoolSize: 50
+    minPoolSize: 1
+
+rules:
+- !DB_DISCOVERY
+  dataSources:
+    readwrite_ds:
+      dataSourceNames:
+        - ds_0
+        - ds_1
+        - ds_2
+      discoveryHeartbeatName: mgr-heartbeat
+      discoveryTypeName: mgr
+  discoveryHeartbeats:
+    mgr-heartbeat:
+      props:
+        keep-alive-cron: '0/5 * * * * ?'
+  discoveryTypes:
+    mgr:
+      type: MGR
+      props:
+        group-name: 92504d5b-6dec-11e8-91ea-246e9612aaf1