1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.proxy.backend.handler.distsql.ral.queryable;
19
20 import org.apache.commons.codec.binary.Base64;
21 import org.apache.shardingsphere.distsql.handler.engine.query.DistSQLQueryExecutor;
22 import org.apache.shardingsphere.distsql.statement.ral.queryable.export.ExportMetaDataStatement;
23 import org.apache.shardingsphere.globalclock.provider.GlobalClockProvider;
24 import org.apache.shardingsphere.globalclock.rule.GlobalClockRule;
25 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
26 import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
27 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
28 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
29 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
30 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
31 import org.apache.shardingsphere.infra.util.json.JsonUtils;
32 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
33 import org.apache.shardingsphere.infra.yaml.config.swapper.rule.YamlRuleConfigurationSwapper;
34 import org.apache.shardingsphere.mode.manager.ContextManager;
35 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
36 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedClusterInfo;
37 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedMetaData;
38 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedSnapshotInfo;
39 import org.apache.shardingsphere.proxy.backend.util.ExportUtils;
40
41 import java.time.LocalDateTime;
42 import java.util.Arrays;
43 import java.util.Collection;
44 import java.util.Collections;
45 import java.util.LinkedHashMap;
46 import java.util.Map;
47 import java.util.Map.Entry;
48 import java.util.Properties;
49
50
51
52
53 public final class ExportMetaDataExecutor implements DistSQLQueryExecutor<ExportMetaDataStatement> {
54
55 @Override
56 public Collection<String> getColumnNames(final ExportMetaDataStatement sqlStatement) {
57 return Arrays.asList("id", "create_time", "cluster_info");
58 }
59
60 @Override
61 public Collection<LocalDataQueryResultRow> getRows(final ExportMetaDataStatement sqlStatement, final ContextManager contextManager) {
62 String exportedData = generateExportData(contextManager.getMetaDataContexts().getMetaData());
63 if (sqlStatement.getFilePath().isPresent()) {
64 String filePath = sqlStatement.getFilePath().get();
65 ExportUtils.exportToFile(filePath, exportedData);
66 return Collections.singleton(new LocalDataQueryResultRow(contextManager.getInstanceContext().getInstance().getCurrentInstanceId(), LocalDateTime.now(),
67 String.format("Successfully exported to:'%s'", filePath)));
68 }
69 return Collections.singleton(new LocalDataQueryResultRow(
70 contextManager.getInstanceContext().getInstance().getCurrentInstanceId(), LocalDateTime.now(), Base64.encodeBase64String(exportedData.getBytes())));
71 }
72
73 private String generateExportData(final ShardingSphereMetaData metaData) {
74 ProxyContext proxyContext = ProxyContext.getInstance();
75 ExportedMetaData exportedMetaData = new ExportedMetaData();
76 exportedMetaData.setDatabases(getDatabases(proxyContext));
77 exportedMetaData.setProps(generatePropsData(metaData.getProps().getProps()));
78 exportedMetaData.setRules(generateRulesData(metaData.getGlobalRuleMetaData().getConfigurations()));
79 ExportedClusterInfo exportedClusterInfo = new ExportedClusterInfo();
80 exportedClusterInfo.setMetaData(exportedMetaData);
81 generateSnapshotInfo(metaData, exportedClusterInfo);
82 return JsonUtils.toJsonString(exportedClusterInfo);
83 }
84
85 private Map<String, String> getDatabases(final ProxyContext proxyContext) {
86 Map<String, String> result = new LinkedHashMap<>();
87 proxyContext.getAllDatabaseNames().forEach(each -> {
88 ShardingSphereDatabase database = proxyContext.getContextManager().getDatabase(each);
89 if (database.getResourceMetaData().getAllInstanceDataSourceNames().isEmpty()) {
90 return;
91 }
92 result.put(each, ExportUtils.generateExportDatabaseData(database));
93 });
94 return result;
95 }
96
97 private String generatePropsData(final Properties props) {
98 if (props.isEmpty()) {
99 return "";
100 }
101 StringBuilder result = new StringBuilder();
102 result.append("props:").append(System.lineSeparator());
103 props.forEach((key, value) -> result.append(" ").append(key).append(": ").append(value).append(System.lineSeparator()));
104 return result.toString();
105 }
106
107 @SuppressWarnings({"rawtypes", "unchecked"})
108 private String generateRulesData(final Collection<RuleConfiguration> rules) {
109 if (rules.isEmpty()) {
110 return "";
111 }
112 StringBuilder result = new StringBuilder();
113 result.append("rules:").append(System.lineSeparator());
114 for (Entry<RuleConfiguration, YamlRuleConfigurationSwapper> entry : OrderedSPILoader.getServices(YamlRuleConfigurationSwapper.class, rules).entrySet()) {
115 result.append(YamlEngine.marshal(Collections.singletonList(entry.getValue().swapToYamlConfiguration(entry.getKey()))));
116 }
117 return result.toString();
118 }
119
120 private void generateSnapshotInfo(final ShardingSphereMetaData metaData, final ExportedClusterInfo exportedClusterInfo) {
121 GlobalClockRule globalClockRule = metaData.getGlobalRuleMetaData().getSingleRule(GlobalClockRule.class);
122 if (globalClockRule.getConfiguration().isEnabled()) {
123 GlobalClockProvider globalClockProvider = TypedSPILoader.getService(GlobalClockProvider.class,
124 globalClockRule.getGlobalClockProviderType(), globalClockRule.getConfiguration().getProps());
125 long csn = globalClockProvider.getCurrentTimestamp();
126 ExportedSnapshotInfo snapshotInfo = new ExportedSnapshotInfo();
127 snapshotInfo.setCsn(String.valueOf(csn));
128 snapshotInfo.setCreateTime(LocalDateTime.now());
129 exportedClusterInfo.setSnapshotInfo(snapshotInfo);
130 }
131 }
132
133 @Override
134 public Class<ExportMetaDataStatement> getType() {
135 return ExportMetaDataStatement.class;
136 }
137 }