1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.metadata;
19
20 import lombok.AccessLevel;
21 import lombok.Getter;
22 import lombok.SneakyThrows;
23 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
24 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
25 import org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigurationProperties;
26 import org.apache.shardingsphere.infra.datasource.pool.destroyer.DataSourcePoolDestroyer;
27 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
28 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabaseFactory;
29 import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
30 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
31 import org.apache.shardingsphere.infra.metadata.identifier.ShardingSphereIdentifier;
32 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
33 import org.apache.shardingsphere.infra.rule.attribute.datasource.StaticDataSourceRuleAttribute;
34 import org.apache.shardingsphere.infra.rule.scope.GlobalRule;
35 import org.apache.shardingsphere.infra.rule.scope.GlobalRule.GlobalRuleChangedType;
36
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.LinkedList;
40 import java.util.Map;
41 import java.util.Optional;
42 import java.util.Properties;
43 import java.util.concurrent.ConcurrentHashMap;
44 import java.util.stream.Collectors;
45
46
47
48
49 @Getter
50 public final class ShardingSphereMetaData implements AutoCloseable {
51
52 @Getter(AccessLevel.NONE)
53 private final Map<ShardingSphereIdentifier, ShardingSphereDatabase> databases;
54
55 private final ResourceMetaData globalResourceMetaData;
56
57 private final RuleMetaData globalRuleMetaData;
58
59 private final ConfigurationProperties props;
60
61 private final TemporaryConfigurationProperties temporaryProps;
62
63 public ShardingSphereMetaData() {
64 this(Collections.emptyList(), new ResourceMetaData(Collections.emptyMap()), new RuleMetaData(Collections.emptyList()), new ConfigurationProperties(new Properties()));
65 }
66
67 public ShardingSphereMetaData(final Collection<ShardingSphereDatabase> databases, final ResourceMetaData globalResourceMetaData,
68 final RuleMetaData globalRuleMetaData, final ConfigurationProperties props) {
69 this.databases = new ConcurrentHashMap<>(databases.stream().collect(Collectors.toMap(each -> new ShardingSphereIdentifier(each.getName()), each -> each)));
70 this.globalResourceMetaData = globalResourceMetaData;
71 this.globalRuleMetaData = globalRuleMetaData;
72 this.props = props;
73 temporaryProps = new TemporaryConfigurationProperties(props.getProps());
74 }
75
76
77
78
79
80
81 public Collection<ShardingSphereDatabase> getAllDatabases() {
82 return databases.values();
83 }
84
85
86
87
88
89
90
91 public boolean containsDatabase(final String databaseName) {
92 return databases.containsKey(new ShardingSphereIdentifier(databaseName));
93 }
94
95
96
97
98
99
100
101 public ShardingSphereDatabase getDatabase(final String databaseName) {
102 return databases.get(new ShardingSphereIdentifier(databaseName));
103 }
104
105
106
107
108
109
110
111
112 public void addDatabase(final String databaseName, final DatabaseType protocolType, final ConfigurationProperties props) {
113 ShardingSphereDatabase database = ShardingSphereDatabaseFactory.create(databaseName, protocolType, props);
114 databases.put(new ShardingSphereIdentifier(database.getName()), database);
115 globalRuleMetaData.getRules().forEach(each -> ((GlobalRule) each).refresh(databases.values(), GlobalRuleChangedType.DATABASE_CHANGED));
116 }
117
118
119
120
121
122
123 public void putDatabase(final ShardingSphereDatabase database) {
124 databases.put(new ShardingSphereIdentifier(database.getName()), database);
125 }
126
127
128
129
130
131
132 public void dropDatabase(final String databaseName) {
133 cleanResources(databases.remove(new ShardingSphereIdentifier(databaseName)));
134 }
135
136 @SneakyThrows(Exception.class)
137 private void cleanResources(final ShardingSphereDatabase database) {
138 globalRuleMetaData.getRules().forEach(each -> ((GlobalRule) each).refresh(databases.values(), GlobalRuleChangedType.DATABASE_CHANGED));
139 for (ShardingSphereRule each : database.getRuleMetaData().getRules()) {
140 if (each instanceof AutoCloseable) {
141 ((AutoCloseable) each).close();
142 }
143 }
144 database.getRuleMetaData().getAttributes(StaticDataSourceRuleAttribute.class).forEach(StaticDataSourceRuleAttribute::cleanStorageNodeDataSources);
145 Optional.ofNullable(database.getResourceMetaData())
146 .ifPresent(optional -> optional.getStorageUnits().values().forEach(each -> new DataSourcePoolDestroyer(each.getDataSource()).asyncDestroy()));
147 }
148
149 @SneakyThrows(Exception.class)
150 @Override
151 public void close() {
152 for (ShardingSphereRule each : getAllRules()) {
153 if (each instanceof AutoCloseable) {
154 ((AutoCloseable) each).close();
155 }
156 }
157 }
158
159 private Collection<ShardingSphereRule> getAllRules() {
160 Collection<ShardingSphereRule> result = new LinkedList<>(globalRuleMetaData.getRules());
161 getAllDatabases().stream().map(each -> each.getRuleMetaData().getRules()).forEach(result::addAll);
162 return result;
163 }
164 }