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