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.AccessLevel;
21 import lombok.Getter;
22 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
23 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
24 import org.apache.shardingsphere.infra.config.rule.decorator.RuleConfigurationDecorator;
25 import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
26 import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException;
27 import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
28 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
29 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
30 import org.apache.shardingsphere.infra.metadata.identifier.ShardingSphereIdentifier;
31 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
32 import org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute;
33 import org.apache.shardingsphere.infra.rule.attribute.datasource.DataSourceMapperRuleAttribute;
34 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
35
36 import javax.sql.DataSource;
37 import java.util.Collection;
38 import java.util.LinkedHashMap;
39 import java.util.LinkedList;
40 import java.util.Map;
41 import java.util.Map.Entry;
42 import java.util.Optional;
43 import java.util.concurrent.ConcurrentHashMap;
44 import java.util.stream.Collectors;
45
46
47
48
49 @Getter
50 public final class ShardingSphereDatabase {
51
52 private final String name;
53
54 private final DatabaseType protocolType;
55
56 private final ResourceMetaData resourceMetaData;
57
58 private final RuleMetaData ruleMetaData;
59
60 @Getter(AccessLevel.NONE)
61 private final Map<ShardingSphereIdentifier, ShardingSphereSchema> schemas;
62
63 public ShardingSphereDatabase(final String name, final DatabaseType protocolType, final ResourceMetaData resourceMetaData,
64 final RuleMetaData ruleMetaData, final Collection<ShardingSphereSchema> schemas) {
65 this.name = name;
66 this.protocolType = protocolType;
67 this.resourceMetaData = resourceMetaData;
68 this.ruleMetaData = ruleMetaData;
69 this.schemas = new ConcurrentHashMap<>(schemas.stream().collect(Collectors.toMap(each -> new ShardingSphereIdentifier(each.getName()), each -> each)));
70 }
71
72
73
74
75
76
77 public Collection<ShardingSphereSchema> getAllSchemas() {
78 return schemas.values();
79 }
80
81
82
83
84
85
86
87 public boolean containsSchema(final String schemaName) {
88 return schemas.containsKey(new ShardingSphereIdentifier(schemaName));
89 }
90
91
92
93
94
95
96
97 public ShardingSphereSchema getSchema(final String schemaName) {
98 return schemas.get(new ShardingSphereIdentifier(schemaName));
99 }
100
101
102
103
104
105
106 public void addSchema(final ShardingSphereSchema schema) {
107 schemas.put(new ShardingSphereIdentifier(schema.getName()), schema);
108 }
109
110
111
112
113
114
115 public void dropSchema(final String schemaName) {
116 schemas.remove(new ShardingSphereIdentifier(schemaName));
117 }
118
119
120
121
122
123
124 public boolean isComplete() {
125 return !ruleMetaData.getRules().isEmpty() && !resourceMetaData.getStorageUnits().isEmpty();
126 }
127
128
129
130
131
132
133 public boolean containsDataSource() {
134 return !resourceMetaData.getStorageUnits().isEmpty();
135 }
136
137
138
139
140 public synchronized void reloadRules() {
141 Collection<ShardingSphereRule> toBeReloadedRules = ruleMetaData.getRules().stream()
142 .filter(each -> each.getAttributes().findAttribute(MutableDataNodeRuleAttribute.class).isPresent()).collect(Collectors.toList());
143 RuleConfiguration ruleConfig = toBeReloadedRules.stream().map(ShardingSphereRule::getConfiguration).findFirst().orElse(null);
144 Collection<ShardingSphereRule> rules = new LinkedList<>(ruleMetaData.getRules());
145 toBeReloadedRules.stream().findFirst().ifPresent(optional -> {
146 rules.removeAll(toBeReloadedRules);
147 Map<String, DataSource> dataSources = resourceMetaData.getStorageUnits().entrySet().stream()
148 .collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getDataSource(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
149 rules.add(optional.getAttributes().getAttribute(MutableDataNodeRuleAttribute.class).reloadRule(ruleConfig, name, dataSources, rules));
150 });
151 ruleMetaData.getRules().clear();
152 ruleMetaData.getRules().addAll(rules);
153 }
154
155
156
157
158
159
160 public void checkStorageUnitsExisted(final Collection<String> storageUnitNames) {
161 Collection<String> notExistedDataSources = resourceMetaData.getNotExistedDataSources(storageUnitNames);
162 Collection<String> logicDataSources = ruleMetaData.getAttributes(DataSourceMapperRuleAttribute.class).stream()
163 .flatMap(each -> each.getDataSourceMapper().keySet().stream()).collect(Collectors.toSet());
164 notExistedDataSources.removeIf(logicDataSources::contains);
165 ShardingSpherePreconditions.checkMustEmpty(notExistedDataSources, () -> new MissingRequiredStorageUnitsException(name, notExistedDataSources));
166 }
167
168
169
170
171
172
173
174 @SuppressWarnings({"unchecked", "rawtypes"})
175 public RuleConfiguration decorateRuleConfiguration(final RuleConfiguration ruleConfig) {
176 Optional<RuleConfigurationDecorator> decorator = TypedSPILoader.findService(RuleConfigurationDecorator.class, ruleConfig.getClass());
177 if (!decorator.isPresent()) {
178 return ruleConfig;
179 }
180 Map<String, DataSource> dataSources = resourceMetaData.getStorageUnits().entrySet().stream()
181 .collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getDataSource(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
182 return decorator.get().decorate(name, dataSources, ruleMetaData.getRules(), ruleConfig);
183 }
184 }