You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by me...@apache.org on 2022/06/19 23:45:00 UTC

[shardingsphere] branch master updated: Decouple ExportDatabaseConfigurationHandler and concrete rules (#18428)

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

menghaoran 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 e08fc39855d Decouple ExportDatabaseConfigurationHandler and concrete rules (#18428)
e08fc39855d is described below

commit e08fc39855de30af984ac3c033647e5ddbbb6151
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Mon Jun 20 07:44:51 2022 +0800

    Decouple ExportDatabaseConfigurationHandler and concrete rules (#18428)
---
 .../ExportDatabaseConfigurationHandler.java        | 198 ++++++---------------
 .../ExportDatabaseConfigurationHandlerTest.java    |   6 +-
 2 files changed, 56 insertions(+), 148 deletions(-)

diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandler.java
index 451661a95b6..8d2254e5969 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandler.java
@@ -18,11 +18,7 @@
 package org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.queryable;
 
 import com.google.common.base.Strings;
-import org.apache.shardingsphere.dbdiscovery.api.config.DatabaseDiscoveryRuleConfiguration;
-import org.apache.shardingsphere.dbdiscovery.yaml.swapper.DatabaseDiscoveryRuleConfigurationYamlSwapper;
 import org.apache.shardingsphere.distsql.parser.statement.ral.common.queryable.ExportDatabaseConfigurationStatement;
-import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
-import org.apache.shardingsphere.encrypt.yaml.swapper.EncryptRuleConfigurationYamlSwapper;
 import org.apache.shardingsphere.infra.config.RuleConfiguration;
 import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
 import org.apache.shardingsphere.infra.datasource.props.DataSourcePropertiesCreator;
@@ -30,17 +26,13 @@ import org.apache.shardingsphere.infra.exception.DatabaseNotExistedException;
 import org.apache.shardingsphere.infra.exception.ShardingSphereException;
 import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.yaml.config.swapper.YamlRuleConfigurationSwapper;
+import org.apache.shardingsphere.infra.yaml.config.swapper.YamlRuleConfigurationSwapperFactory;
 import org.apache.shardingsphere.infra.yaml.engine.YamlEngine;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.exception.NoDatabaseSelectedException;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.QueryableRALBackendHandler;
-import org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
-import org.apache.shardingsphere.readwritesplitting.yaml.swapper.ReadwriteSplittingRuleConfigurationYamlSwapper;
-import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
-import org.apache.shardingsphere.shadow.yaml.swapper.ShadowRuleConfigurationYamlSwapper;
-import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
-import org.apache.shardingsphere.sharding.yaml.swapper.ShardingRuleConfigurationYamlSwapper;
 
 import javax.sql.DataSource;
 import java.io.File;
@@ -48,8 +40,6 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Map.Entry;
 
 /**
@@ -57,167 +47,85 @@ import java.util.Map.Entry;
  */
 public final class ExportDatabaseConfigurationHandler extends QueryableRALBackendHandler<ExportDatabaseConfigurationStatement> {
     
-    private static final String RESULT = "result";
-    
-    private static final String COLON = ":";
-    
-    private static final String SPACE = " ";
-    
-    private static final String NEWLINE = "\n";
-    
-    private static final String COLON_SPACE = COLON + SPACE;
-    
-    private static final String COLON_NEWLINE = COLON + NEWLINE;
-    
-    private static final String INDENT = SPACE + SPACE;
-    
-    private static final int ZERO = 0;
-    
-    private static final int ONE = 1;
-    
-    private static final int TWO = 2;
-    
-    private static final String SHARDING = "sharding";
-    
-    private static final String READWRITE_SPLITTING = "readwrite_splitting";
-    
-    private static final String DB_DISCOVERY = "db_discovery";
-    
-    private static final String ENCRYPT = "encrypt";
-    
-    private static final String SHADOW = "shadow";
-    
-    private static final Map<String, Class<? extends RuleConfiguration>> FEATURE_MAP = new HashMap<>(5, 1);
-    
-    static {
-        FEATURE_MAP.put(SHARDING, ShardingRuleConfiguration.class);
-        FEATURE_MAP.put(READWRITE_SPLITTING, ReadwriteSplittingRuleConfiguration.class);
-        FEATURE_MAP.put(DB_DISCOVERY, DatabaseDiscoveryRuleConfiguration.class);
-        FEATURE_MAP.put(ENCRYPT, EncryptRuleConfiguration.class);
-        FEATURE_MAP.put(SHADOW, ShadowRuleConfiguration.class);
-    }
-    
     @Override
     protected Collection<String> getColumnNames() {
-        return Collections.singletonList(RESULT);
+        return Collections.singleton("result");
     }
     
     @Override
     protected Collection<LocalDataQueryResultRow> getRows(final ContextManager contextManager) {
-        String databaseName = getDatabaseName();
-        ShardingSphereDatabase database = ProxyContext.getInstance().getDatabase(databaseName);
-        StringBuilder result = new StringBuilder();
-        configItem(ZERO, "databaseName", databaseName, result);
-        getDataSourcesConfig(database, result);
-        getRuleConfigurations(database.getRuleMetaData().getConfigurations(), result);
-        if (!getSqlStatement().getFilePath().isPresent()) {
-            return Collections.singleton(new LocalDataQueryResultRow(result.toString()));
-        }
-        File outFile = new File(getSqlStatement().getFilePath().get());
-        if (!outFile.exists()) {
-            outFile.getParentFile().mkdirs();
-        }
-        try (FileOutputStream stream = new FileOutputStream(outFile)) {
-            stream.write(result.toString().getBytes());
-            stream.flush();
-        } catch (final IOException ex) {
-            throw new ShardingSphereException(ex);
+        String exportedData = generateExportData(getDatabaseName());
+        if (getSqlStatement().getFilePath().isPresent()) {
+            String filePath = getSqlStatement().getFilePath().get();
+            exportToFile(filePath, exportedData);
+            return Collections.singleton(new LocalDataQueryResultRow(String.format("Successfully exported to:'%s'", filePath)));
         }
-        return Collections.singleton(new LocalDataQueryResultRow(String.format("Successfully exported to:'%s'", getSqlStatement().getFilePath().get())));
+        return Collections.singleton(new LocalDataQueryResultRow(exportedData));
     }
     
-    private void getDataSourcesConfig(final ShardingSphereDatabase database, final StringBuilder result) {
-        if (null == database.getResource().getDataSources() || database.getResource().getDataSources().isEmpty()) {
-            return;
-        }
-        configItem(ZERO, "dataSources", result);
-        for (Entry<String, DataSource> each : database.getResource().getDataSources().entrySet()) {
-            configItem(ONE, each.getKey(), result);
-            DataSourceProperties dataSourceProps = DataSourcePropertiesCreator.create(each.getValue());
-            dataSourceProps.getConnectionPropertySynonyms().getStandardProperties().forEach((key, value) -> configItem(TWO, key, value, result));
-            dataSourceProps.getPoolPropertySynonyms().getStandardProperties().forEach((key, value) -> configItem(TWO, key, value, result));
-        }
-    }
-    
-    private void getRuleConfigurations(final Collection<RuleConfiguration> ruleConfigs, final StringBuilder result) {
-        if (null == ruleConfigs || ruleConfigs.isEmpty()) {
-            return;
+    private String getDatabaseName() {
+        String result = getSqlStatement().getDatabase().isPresent() ? getSqlStatement().getDatabase().get().getIdentifier().getValue() : getConnectionSession().getDatabaseName();
+        if (Strings.isNullOrEmpty(result)) {
+            throw new NoDatabaseSelectedException();
         }
-        configItem(ZERO, "rules", result);
-        ruleConfigs.forEach(each -> {
-            getRulesConfigForSharding(each, result);
-            getRulesConfigForReadwriteSplitting(each, result);
-            getRulesConfigForDBDiscovery(each, result);
-            getRulesConfigForEncrypt(each, result);
-            getRulesConfigForShadow(each, result);
-        });
-    }
-    
-    private boolean matchFeature(final RuleConfiguration ruleConfig, final String feature) {
-        return null != ruleConfig && ruleConfig.getClass().getCanonicalName().equalsIgnoreCase(FEATURE_MAP.get(feature).getCanonicalName());
-    }
-    
-    private void getRulesConfigForSharding(final RuleConfiguration ruleConfig, final StringBuilder result) {
-        if (matchFeature(ruleConfig, SHARDING)) {
-            result.append(YamlEngine.marshal(Collections.singletonList(new ShardingRuleConfigurationYamlSwapper().swapToYamlConfiguration((ShardingRuleConfiguration) ruleConfig))));
+        if (!ProxyContext.getInstance().getAllDatabaseNames().contains(result)) {
+            throw new DatabaseNotExistedException(result);
         }
+        return result;
     }
     
-    private void getRulesConfigForReadwriteSplitting(final RuleConfiguration ruleConfig, final StringBuilder result) {
-        if (matchFeature(ruleConfig, READWRITE_SPLITTING)) {
-            result.append(YamlEngine.marshal(
-                    Collections.singletonList(new ReadwriteSplittingRuleConfigurationYamlSwapper().swapToYamlConfiguration((ReadwriteSplittingRuleConfiguration) ruleConfig))));
-        }
+    private String generateExportData(final String databaseName) {
+        StringBuilder result = new StringBuilder();
+        ShardingSphereDatabase database = ProxyContext.getInstance().getDatabase(databaseName);
+        appendDatabaseName(databaseName, result);
+        appendDataSourceConfigurations(database, result);
+        appendRuleConfigurations(database.getRuleMetaData().getConfigurations(), result);
+        return result.toString();
     }
     
-    private void getRulesConfigForDBDiscovery(final RuleConfiguration ruleConfig, final StringBuilder result) {
-        if (matchFeature(ruleConfig, DB_DISCOVERY)) {
-            result.append(YamlEngine.marshal(Collections.singletonList(new DatabaseDiscoveryRuleConfigurationYamlSwapper().swapToYamlConfiguration((DatabaseDiscoveryRuleConfiguration) ruleConfig))));
-        }
+    private void appendDatabaseName(final String databaseName, final StringBuilder stringBuilder) {
+        stringBuilder.append("databaseName").append(": ").append(databaseName).append("\n");
     }
     
-    private void getRulesConfigForEncrypt(final RuleConfiguration ruleConfig, final StringBuilder result) {
-        if (matchFeature(ruleConfig, ENCRYPT)) {
-            result.append(YamlEngine.marshal(Collections.singletonList(new EncryptRuleConfigurationYamlSwapper().swapToYamlConfiguration((EncryptRuleConfiguration) ruleConfig))));
+    private void appendDataSourceConfigurations(final ShardingSphereDatabase database, final StringBuilder stringBuilder) {
+        if (database.getResource().getDataSources().isEmpty()) {
+            return;
         }
-    }
-    
-    private void getRulesConfigForShadow(final RuleConfiguration ruleConfig, final StringBuilder result) {
-        if (matchFeature(ruleConfig, SHADOW)) {
-            result.append(YamlEngine.marshal(Collections.singletonList(new ShadowRuleConfigurationYamlSwapper().swapToYamlConfiguration((ShadowRuleConfiguration) ruleConfig))));
+        stringBuilder.append("dataSources").append(":\n");
+        for (Entry<String, DataSource> entry : database.getResource().getDataSources().entrySet()) {
+            appendDataSourceConfiguration(entry.getKey(), entry.getValue(), stringBuilder);
         }
     }
     
-    private void configItem(final int indent, final Object key, final StringBuilder result) {
-        result.append(indent(indent)).append(key).append(COLON_NEWLINE);
-    }
-    
-    private void configItem(final int indent, final Object key, final Object value, final StringBuilder result) {
-        result.append(indent(indent)).append(key).append(COLON_SPACE).append(value).append(NEWLINE);
+    private void appendDataSourceConfiguration(final String name, final DataSource dataSource, final StringBuilder stringBuilder) {
+        stringBuilder.append("  ").append(name).append(":\n");
+        DataSourceProperties dataSourceProps = DataSourcePropertiesCreator.create(dataSource);
+        dataSourceProps.getConnectionPropertySynonyms().getStandardProperties().forEach((key, value) -> stringBuilder.append("    ").append(key).append(": ").append(value).append("\n"));
+        dataSourceProps.getPoolPropertySynonyms().getStandardProperties().forEach((key, value) -> stringBuilder.append("    ").append(key).append(": ").append(value).append("\n"));
     }
     
-    private String indent(final int count) {
-        if (count <= 0) {
-            return "";
-        }
-        if (1 == count) {
-            return INDENT;
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private void appendRuleConfigurations(final Collection<RuleConfiguration> ruleConfigs, final StringBuilder stringBuilder) {
+        if (ruleConfigs.isEmpty()) {
+            return;
         }
-        StringBuilder result = new StringBuilder();
-        for (int i = 0; i < count; i++) {
-            result.append(INDENT);
+        stringBuilder.append("rules").append(":\n");
+        for (Entry<RuleConfiguration, YamlRuleConfigurationSwapper> entry : YamlRuleConfigurationSwapperFactory.getInstanceMapByRuleConfigurations(ruleConfigs).entrySet()) {
+            stringBuilder.append(YamlEngine.marshal(Collections.singleton(entry.getValue().swapToYamlConfiguration(entry.getKey()))));
         }
-        return result.toString();
     }
     
-    private String getDatabaseName() {
-        String result = getSqlStatement().getDatabase().isPresent() ? getSqlStatement().getDatabase().get().getIdentifier().getValue() : getConnectionSession().getDatabaseName();
-        if (Strings.isNullOrEmpty(result)) {
-            throw new NoDatabaseSelectedException();
+    @SuppressWarnings("ResultOfMethodCallIgnored")
+    private void exportToFile(final String filePath, final String exportedData) {
+        File file = new File(filePath);
+        if (!file.exists()) {
+            file.getParentFile().mkdirs();
         }
-        if (!ProxyContext.getInstance().getAllDatabaseNames().contains(result)) {
-            throw new DatabaseNotExistedException(result);
+        try (FileOutputStream output = new FileOutputStream(file)) {
+            output.write(exportedData.getBytes());
+            output.flush();
+        } catch (final IOException ex) {
+            throw new ShardingSphereException(ex);
         }
-        return result;
     }
 }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandlerTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandlerTest.java
index 9a6579c49a6..4595c0e02cf 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandlerTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/queryable/ExportDatabaseConfigurationHandlerTest.java
@@ -62,7 +62,7 @@ public final class ExportDatabaseConfigurationHandlerTest extends ProxyContextRe
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
         when(database.getSchemas().get("sharding_db")).thenReturn(new ShardingSphereSchema(createTableMap()));
         when(database.getResource().getDataSources()).thenReturn(createDataSourceMap());
-        when(database.getRuleMetaData().getConfigurations()).thenReturn(Collections.singletonList(createShardingRuleConfiguration()));
+        when(database.getRuleMetaData().getConfigurations()).thenReturn(Collections.singleton(createShardingRuleConfiguration()));
         when(contextManager.getMetaDataContexts().getMetaData().getDatabases()).thenReturn(Collections.singletonMap("sharding_db", database));
         ProxyContext.init(contextManager);
     }
@@ -117,8 +117,8 @@ public final class ExportDatabaseConfigurationHandlerTest extends ProxyContextRe
     }
     
     private Map<String, ShardingSphereTable> createTableMap() {
-        Collection<ShardingSphereColumn> columns = Collections.singletonList(new ShardingSphereColumn("order_id", 0, false, false, false));
-        Collection<ShardingSphereIndex> indexes = Collections.singletonList(new ShardingSphereIndex("primary"));
+        Collection<ShardingSphereColumn> columns = Collections.singleton(new ShardingSphereColumn("order_id", 0, false, false, false));
+        Collection<ShardingSphereIndex> indexes = Collections.singleton(new ShardingSphereIndex("primary"));
         return Collections.singletonMap("t_order", new ShardingSphereTable("t_order", columns, indexes, Collections.emptyList()));
     }