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.shardingsphere.distsql.handler.engine.query.DistSQLQueryExecutor;
21 import org.apache.shardingsphere.distsql.statement.ral.queryable.export.ExportStorageNodesStatement;
22 import org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties;
23 import org.apache.shardingsphere.infra.datasource.pool.props.creator.DataSourcePoolPropertiesCreator;
24 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
25 import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
26 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
27 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
28 import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
29 import org.apache.shardingsphere.infra.util.json.JsonUtils;
30 import org.apache.shardingsphere.mode.manager.ContextManager;
31 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedStorageNode;
32 import org.apache.shardingsphere.proxy.backend.distsql.export.ExportedStorageNodes;
33 import org.apache.shardingsphere.proxy.backend.util.ExportUtils;
34
35 import java.time.LocalDateTime;
36 import java.util.Arrays;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.LinkedHashMap;
40 import java.util.Map;
41 import java.util.Map.Entry;
42
43
44
45
46 public final class ExportStorageNodesExecutor implements DistSQLQueryExecutor<ExportStorageNodesStatement> {
47
48 @Override
49 public Collection<String> getColumnNames(final ExportStorageNodesStatement sqlStatement) {
50 return Arrays.asList("id", "create_time", "storage_nodes");
51 }
52
53 @Override
54 public Collection<LocalDataQueryResultRow> getRows(final ExportStorageNodesStatement sqlStatement, final ContextManager contextManager) {
55 checkSQLStatement(contextManager.getMetaDataContexts().getMetaData(), sqlStatement);
56 String exportedData = generateExportData(contextManager.getMetaDataContexts().getMetaData(), sqlStatement);
57 if (sqlStatement.getFilePath().isPresent()) {
58 String filePath = sqlStatement.getFilePath().get();
59 ExportUtils.exportToFile(filePath, exportedData);
60 return Collections.singleton(new LocalDataQueryResultRow(contextManager.getInstanceContext().getInstance().getCurrentInstanceId(), LocalDateTime.now(),
61 String.format("Successfully exported to:'%s'", filePath)));
62 }
63 return Collections.singleton(
64 new LocalDataQueryResultRow(contextManager.getInstanceContext().getInstance().getCurrentInstanceId(), LocalDateTime.now(), exportedData));
65 }
66
67 private void checkSQLStatement(final ShardingSphereMetaData metaData, final ExportStorageNodesStatement sqlStatement) {
68 ShardingSpherePreconditions.checkState(null == sqlStatement.getDatabaseName() || null != metaData.getDatabase(sqlStatement.getDatabaseName()),
69 () -> new IllegalArgumentException(String.format("database %s is not existed", sqlStatement.getDatabaseName())));
70 }
71
72 private String generateExportData(final ShardingSphereMetaData metaData, final ExportStorageNodesStatement sqlStatement) {
73 ExportedStorageNodes storageNodes = new ExportedStorageNodes();
74 storageNodes.setStorageNodes(null == sqlStatement.getDatabaseName()
75 ? getAllStorageNodes(metaData)
76 : generateDatabaseExportStorageNodesData(metaData.getDatabase(sqlStatement.getDatabaseName())));
77 return JsonUtils.toJsonString(storageNodes);
78 }
79
80 private Map<String, Collection<ExportedStorageNode>> getAllStorageNodes(final ShardingSphereMetaData metaData) {
81 Map<String, Collection<ExportedStorageNode>> storageNodes = new LinkedHashMap<>();
82 metaData.getDatabases().values().forEach(each -> {
83 if (each.getResourceMetaData().getAllInstanceDataSourceNames().isEmpty()) {
84 return;
85 }
86 storageNodes.putAll(generateDatabaseExportStorageNodesData(each));
87 });
88 return storageNodes;
89 }
90
91 private Map<String, Collection<ExportedStorageNode>> generateDatabaseExportStorageNodesData(final ShardingSphereDatabase database) {
92 Map<String, ExportedStorageNode> storageNodes = new LinkedHashMap<>();
93 for (Entry<String, StorageUnit> entry : database.getResourceMetaData().getStorageUnits().entrySet()) {
94 ConnectionProperties connectionProps = database.getResourceMetaData().getStorageUnits().get(entry.getKey()).getConnectionProperties();
95 String databaseInstanceIp = getDatabaseInstanceIp(connectionProps);
96 if (storageNodes.containsKey(databaseInstanceIp)) {
97 continue;
98 }
99 Map<String, Object> standardProps = DataSourcePoolPropertiesCreator.create(entry.getValue().getDataSource()).getConnectionPropertySynonyms().getStandardProperties();
100 ExportedStorageNode exportedStorageNode = new ExportedStorageNode(connectionProps.getHostname(), String.valueOf(connectionProps.getPort()),
101 String.valueOf(standardProps.get("username")), String.valueOf(standardProps.get("password")), connectionProps.getCatalog());
102 storageNodes.put(databaseInstanceIp, exportedStorageNode);
103 }
104 return Collections.singletonMap(database.getName(), storageNodes.values());
105 }
106
107 private String getDatabaseInstanceIp(final ConnectionProperties connectionProps) {
108 return String.format("%s:%s", connectionProps.getHostname(), connectionProps.getPort());
109 }
110
111 @Override
112 public Class<ExportStorageNodesStatement> getType() {
113 return ExportStorageNodesStatement.class;
114 }
115 }