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.rule;
19
20 import com.google.common.base.Preconditions;
21 import lombok.Getter;
22 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
23 import org.apache.shardingsphere.infra.datanode.DataNode;
24 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
25 import org.apache.shardingsphere.infra.rule.attribute.RuleAttribute;
26 import org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
27 import org.apache.shardingsphere.infra.rule.attribute.datasource.DataSourceMapperRuleAttribute;
28
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.LinkedHashMap;
32 import java.util.LinkedHashSet;
33 import java.util.LinkedList;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.Optional;
37 import java.util.concurrent.CopyOnWriteArrayList;
38 import java.util.stream.Collectors;
39
40
41
42
43 @Getter
44 public final class RuleMetaData {
45
46 private final Collection<ShardingSphereRule> rules;
47
48 public RuleMetaData(final Collection<ShardingSphereRule> rules) {
49 this.rules = new CopyOnWriteArrayList<>(rules);
50 }
51
52
53
54
55
56
57 public Collection<RuleConfiguration> getConfigurations() {
58 return rules.stream().map(ShardingSphereRule::getConfiguration).collect(Collectors.toList());
59 }
60
61
62
63
64
65
66
67
68 public <T extends ShardingSphereRule> Collection<T> findRules(final Class<T> clazz) {
69 Collection<T> result = new LinkedList<>();
70 for (ShardingSphereRule each : rules) {
71 if (clazz.isAssignableFrom(each.getClass())) {
72 result.add(clazz.cast(each));
73 }
74 }
75 return result;
76 }
77
78
79
80
81
82
83
84
85 public <T extends ShardingSphereRule> Optional<T> findSingleRule(final Class<T> clazz) {
86 Collection<T> foundRules = findRules(clazz);
87 return foundRules.isEmpty() ? Optional.empty() : Optional.of(foundRules.iterator().next());
88 }
89
90
91
92
93
94
95
96
97 public <T extends ShardingSphereRule> T getSingleRule(final Class<T> clazz) {
98 Collection<T> foundRules = findRules(clazz);
99 Preconditions.checkState(1 == foundRules.size(), "Rule `%s` should have and only have one instance.", clazz.getSimpleName());
100 return foundRules.iterator().next();
101 }
102
103
104
105
106
107
108 public Map<String, Collection<Class<? extends ShardingSphereRule>>> getInUsedStorageUnitNameAndRulesMap() {
109 Map<String, Collection<Class<? extends ShardingSphereRule>>> result = new LinkedHashMap<>();
110 for (ShardingSphereRule each : rules) {
111 Collection<String> inUsedStorageUnitNames = getInUsedStorageUnitNames(each);
112 if (!inUsedStorageUnitNames.isEmpty()) {
113 mergeInUsedStorageUnitNameAndRules(result, getInUsedStorageUnitNameAndRulesMap(each, inUsedStorageUnitNames));
114 }
115 }
116 return result;
117 }
118
119 private Map<String, Collection<Class<? extends ShardingSphereRule>>> getInUsedStorageUnitNameAndRulesMap(final ShardingSphereRule rule, final Collection<String> inUsedStorageUnitNames) {
120 Map<String, Collection<Class<? extends ShardingSphereRule>>> result = new LinkedHashMap<>();
121 for (String each : inUsedStorageUnitNames) {
122 if (!result.containsKey(each)) {
123 result.put(each, new LinkedHashSet<>());
124 }
125 result.get(each).add(rule.getClass());
126 }
127 return result;
128 }
129
130 private Collection<String> getInUsedStorageUnitNames(final ShardingSphereRule rule) {
131 Optional<DataSourceMapperRuleAttribute> dataSourceMapperRuleAttribute = rule.getAttributes().findAttribute(DataSourceMapperRuleAttribute.class);
132 if (dataSourceMapperRuleAttribute.isPresent()) {
133 return getInUsedStorageUnitNames(dataSourceMapperRuleAttribute.get());
134 }
135 Optional<DataNodeRuleAttribute> dataNodeRuleAttribute = rule.getAttributes().findAttribute(DataNodeRuleAttribute.class);
136 if (dataNodeRuleAttribute.isPresent()) {
137 return getInUsedStorageUnitNames(dataNodeRuleAttribute.get());
138 }
139 return Collections.emptyList();
140 }
141
142 private Collection<String> getInUsedStorageUnitNames(final DataSourceMapperRuleAttribute ruleAttribute) {
143 return ruleAttribute.getDataSourceMapper().values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
144 }
145
146 private Collection<String> getInUsedStorageUnitNames(final DataNodeRuleAttribute ruleAttribute) {
147 return ruleAttribute.getAllDataNodes().values().stream().flatMap(each -> each.stream().map(DataNode::getDataSourceName).collect(Collectors.toSet()).stream()).collect(Collectors.toSet());
148 }
149
150 private void mergeInUsedStorageUnitNameAndRules(final Map<String, Collection<Class<? extends ShardingSphereRule>>> storageUnitNameAndRules,
151 final Map<String, Collection<Class<? extends ShardingSphereRule>>> toBeMergedStorageUnitNameAndRules) {
152 for (Entry<String, Collection<Class<? extends ShardingSphereRule>>> entry : toBeMergedStorageUnitNameAndRules.entrySet()) {
153 if (storageUnitNameAndRules.containsKey(entry.getKey())) {
154 for (Class<? extends ShardingSphereRule> each : entry.getValue()) {
155 if (!storageUnitNameAndRules.get(entry.getKey()).contains(each)) {
156 storageUnitNameAndRules.get(entry.getKey()).add(each);
157 }
158 }
159 } else {
160 storageUnitNameAndRules.put(entry.getKey(), entry.getValue());
161 }
162 }
163 }
164
165
166
167
168
169
170
171
172 public <T extends RuleAttribute> Collection<T> getAttributes(final Class<T> attributeClass) {
173 Collection<T> result = new LinkedList<>();
174 for (ShardingSphereRule each : rules) {
175 each.getAttributes().findAttribute(attributeClass).ifPresent(result::add);
176 }
177 return result;
178 }
179
180
181
182
183
184
185
186
187 public <T extends RuleAttribute> Optional<T> findAttribute(final Class<T> attributeClass) {
188 for (ShardingSphereRule each : rules) {
189 if (each.getAttributes().findAttribute(attributeClass).isPresent()) {
190 return each.getAttributes().findAttribute(attributeClass);
191 }
192 }
193 return Optional.empty();
194 }
195 }