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 result.computeIfAbsent(each, unused -> new LinkedHashSet<>()).add(rule.getClass());
123 }
124 return result;
125 }
126
127 private Collection<String> getInUsedStorageUnitNames(final ShardingSphereRule rule) {
128 Optional<DataSourceMapperRuleAttribute> dataSourceMapperRuleAttribute = rule.getAttributes().findAttribute(DataSourceMapperRuleAttribute.class);
129 if (dataSourceMapperRuleAttribute.isPresent()) {
130 return getInUsedStorageUnitNames(dataSourceMapperRuleAttribute.get());
131 }
132 Optional<DataNodeRuleAttribute> dataNodeRuleAttribute = rule.getAttributes().findAttribute(DataNodeRuleAttribute.class);
133 if (dataNodeRuleAttribute.isPresent()) {
134 return getInUsedStorageUnitNames(dataNodeRuleAttribute.get());
135 }
136 return Collections.emptyList();
137 }
138
139 private Collection<String> getInUsedStorageUnitNames(final DataSourceMapperRuleAttribute ruleAttribute) {
140 return ruleAttribute.getDataSourceMapper().values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
141 }
142
143 private Collection<String> getInUsedStorageUnitNames(final DataNodeRuleAttribute ruleAttribute) {
144 return ruleAttribute.getAllDataNodes().values().stream().flatMap(each -> each.stream().map(DataNode::getDataSourceName).collect(Collectors.toSet()).stream()).collect(Collectors.toSet());
145 }
146
147 private void mergeInUsedStorageUnitNameAndRules(final Map<String, Collection<Class<? extends ShardingSphereRule>>> storageUnitNameAndRules,
148 final Map<String, Collection<Class<? extends ShardingSphereRule>>> toBeMergedStorageUnitNameAndRules) {
149 for (Entry<String, Collection<Class<? extends ShardingSphereRule>>> entry : toBeMergedStorageUnitNameAndRules.entrySet()) {
150 if (storageUnitNameAndRules.containsKey(entry.getKey())) {
151 for (Class<? extends ShardingSphereRule> each : entry.getValue()) {
152 if (!storageUnitNameAndRules.get(entry.getKey()).contains(each)) {
153 storageUnitNameAndRules.get(entry.getKey()).add(each);
154 }
155 }
156 } else {
157 storageUnitNameAndRules.put(entry.getKey(), entry.getValue());
158 }
159 }
160 }
161
162
163
164
165
166
167
168
169 public <T extends RuleAttribute> Collection<T> getAttributes(final Class<T> attributeClass) {
170 Collection<T> result = new LinkedList<>();
171 for (ShardingSphereRule each : rules) {
172 each.getAttributes().findAttribute(attributeClass).ifPresent(result::add);
173 }
174 return result;
175 }
176
177
178
179
180
181
182
183
184 public <T extends RuleAttribute> Optional<T> findAttribute(final Class<T> attributeClass) {
185 for (ShardingSphereRule each : rules) {
186 if (each.getAttributes().findAttribute(attributeClass).isPresent()) {
187 return each.getAttributes().findAttribute(attributeClass);
188 }
189 }
190 return Optional.empty();
191 }
192 }