1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.metadata.database;
19
20 import lombok.Getter;
21 import org.apache.shardingsphere.infra.config.database.DatabaseConfiguration;
22 import org.apache.shardingsphere.infra.config.database.impl.DataSourceProvidedDatabaseConfiguration;
23 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
24 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
25 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
26 import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
27 import org.apache.shardingsphere.infra.instance.InstanceContext;
28 import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
29 import org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNode;
30 import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
31 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
32 import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilder;
33 import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilderMaterial;
34 import org.apache.shardingsphere.infra.metadata.database.schema.builder.SystemSchemaBuilder;
35 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
36 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
37 import org.apache.shardingsphere.infra.rule.builder.database.DatabaseRulesBuilder;
38 import org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute;
39 import org.apache.shardingsphere.infra.state.datasource.DataSourceStateManager;
40
41 import javax.sql.DataSource;
42 import java.sql.SQLException;
43 import java.util.Collection;
44 import java.util.LinkedHashMap;
45 import java.util.LinkedList;
46 import java.util.Map;
47 import java.util.Map.Entry;
48 import java.util.concurrent.ConcurrentHashMap;
49 import java.util.stream.Collectors;
50
51
52
53
54 @Getter
55 public final class ShardingSphereDatabase {
56
57 private final String name;
58
59 private final DatabaseType protocolType;
60
61 private final ResourceMetaData resourceMetaData;
62
63 private final RuleMetaData ruleMetaData;
64
65 private final Map<String, ShardingSphereSchema> schemas;
66
67 public ShardingSphereDatabase(final String name, final DatabaseType protocolType, final ResourceMetaData resourceMetaData,
68 final RuleMetaData ruleMetaData, final Map<String, ShardingSphereSchema> schemas) {
69 this.name = name;
70 this.protocolType = protocolType;
71 this.resourceMetaData = resourceMetaData;
72 this.ruleMetaData = ruleMetaData;
73 this.schemas = new ConcurrentHashMap<>(schemas.size(), 1F);
74 schemas.forEach((key, value) -> this.schemas.put(key.toLowerCase(), value));
75 }
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public static ShardingSphereDatabase create(final String name, final DatabaseType protocolType, final Map<String, DatabaseType> storageTypes,
90 final DatabaseConfiguration databaseConfig, final ConfigurationProperties props, final InstanceContext instanceContext) throws SQLException {
91 Collection<ShardingSphereRule> databaseRules = DatabaseRulesBuilder.build(name, protocolType, databaseConfig, instanceContext);
92 Map<String, ShardingSphereSchema> schemas = new ConcurrentHashMap<>(GenericSchemaBuilder
93 .build(new GenericSchemaBuilderMaterial(protocolType, storageTypes, DataSourceStateManager.getInstance().getEnabledDataSources(name, databaseConfig), databaseRules,
94 props, new DatabaseTypeRegistry(protocolType).getDefaultSchemaName(name))));
95 SystemSchemaBuilder.build(name, protocolType, props).forEach(schemas::putIfAbsent);
96 return create(name, protocolType, databaseConfig, databaseRules, schemas);
97 }
98
99
100
101
102
103
104
105
106
107 public static ShardingSphereDatabase create(final String name, final DatabaseType protocolType, final ConfigurationProperties props) {
108 DatabaseConfiguration databaseConfig = new DataSourceProvidedDatabaseConfiguration(new LinkedHashMap<>(), new LinkedList<>());
109 return create(name, protocolType, databaseConfig, new LinkedList<>(), SystemSchemaBuilder.build(name, protocolType, props));
110 }
111
112
113
114
115
116
117
118
119
120
121
122 public static ShardingSphereDatabase create(final String name, final DatabaseType protocolType, final DatabaseConfiguration databaseConfig,
123 final Collection<ShardingSphereRule> rules, final Map<String, ShardingSphereSchema> schemas) {
124 ResourceMetaData resourceMetaData = createResourceMetaData(databaseConfig.getDataSources(), databaseConfig.getStorageUnits());
125 RuleMetaData ruleMetaData = new RuleMetaData(rules);
126 return new ShardingSphereDatabase(name, protocolType, resourceMetaData, ruleMetaData, schemas);
127 }
128
129 private static ResourceMetaData createResourceMetaData(final Map<StorageNode, DataSource> dataSources, final Map<String, StorageUnit> storageUnits) {
130 return new ResourceMetaData(dataSources, storageUnits);
131 }
132
133
134
135
136
137
138
139 public boolean containsSchema(final String schemaName) {
140 return schemas.containsKey(schemaName.toLowerCase());
141 }
142
143
144
145
146
147
148
149 public ShardingSphereSchema getSchema(final String schemaName) {
150 return schemas.get(schemaName.toLowerCase());
151 }
152
153
154
155
156
157
158
159 public void addSchema(final String schemaName, final ShardingSphereSchema schema) {
160 schemas.put(schemaName.toLowerCase(), schema);
161 }
162
163
164
165
166
167
168 public void dropSchema(final String schemaName) {
169 schemas.remove(schemaName.toLowerCase());
170 }
171
172
173
174
175
176
177 public boolean isComplete() {
178 return !ruleMetaData.getRules().isEmpty() && !resourceMetaData.getStorageUnits().isEmpty();
179 }
180
181
182
183
184
185
186 public boolean containsDataSource() {
187 return !resourceMetaData.getStorageUnits().isEmpty();
188 }
189
190
191
192
193 public synchronized void reloadRules() {
194 Collection<ShardingSphereRule> toBeReloadedRules = ruleMetaData.getRules().stream()
195 .filter(each -> each.getAttributes().findAttribute(MutableDataNodeRuleAttribute.class).isPresent()).collect(Collectors.toList());
196 RuleConfiguration ruleConfig = toBeReloadedRules.stream().map(ShardingSphereRule::getConfiguration).findFirst().orElse(null);
197 Collection<ShardingSphereRule> rules = new LinkedList<>(ruleMetaData.getRules());
198 toBeReloadedRules.stream().findFirst().ifPresent(optional -> {
199 rules.removeAll(toBeReloadedRules);
200 Map<String, DataSource> dataSources = resourceMetaData.getStorageUnits().entrySet().stream()
201 .collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getDataSource(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
202 rules.add(optional.getAttributes().getAttribute(MutableDataNodeRuleAttribute.class).reloadRule(ruleConfig, name, dataSources, rules));
203 });
204 ruleMetaData.getRules().clear();
205 ruleMetaData.getRules().addAll(rules);
206 }
207 }