1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.rule.builder.database;
19
20 import lombok.AccessLevel;
21 import lombok.NoArgsConstructor;
22 import org.apache.shardingsphere.infra.config.database.DatabaseConfiguration;
23 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
24 import org.apache.shardingsphere.infra.config.rule.checker.RuleConfigurationChecker;
25 import org.apache.shardingsphere.infra.config.rule.function.DistributedRuleConfiguration;
26 import org.apache.shardingsphere.infra.config.rule.function.EnhancedRuleConfiguration;
27 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
28 import org.apache.shardingsphere.infra.instance.InstanceContext;
29 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
30 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
31
32 import javax.sql.DataSource;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.LinkedHashMap;
38 import java.util.LinkedList;
39 import java.util.Map;
40 import java.util.Map.Entry;
41 import java.util.stream.Collectors;
42
43
44
45
46 @NoArgsConstructor(access = AccessLevel.PRIVATE)
47 public final class DatabaseRulesBuilder {
48
49
50
51
52
53
54
55
56
57
58 @SuppressWarnings({"unchecked", "rawtypes"})
59 public static Collection<ShardingSphereRule> build(final String databaseName, final DatabaseType protocolType, final DatabaseConfiguration databaseConfig, final InstanceContext instanceContext) {
60 Collection<ShardingSphereRule> result = new LinkedList<>();
61 for (Entry<RuleConfiguration, DatabaseRuleBuilder> entry : getRuleBuilderMap(databaseConfig).entrySet()) {
62 Map<String, DataSource> dataSources = databaseConfig.getStorageUnits().entrySet().stream()
63 .collect(Collectors.toMap(Entry::getKey, storageUnit -> storageUnit.getValue().getDataSource(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
64 RuleConfigurationChecker configChecker = OrderedSPILoader.getServicesByClass(
65 RuleConfigurationChecker.class, Collections.singleton(entry.getKey().getClass())).get(entry.getKey().getClass());
66 if (null != configChecker) {
67 configChecker.check(databaseName, entry.getKey(), dataSources, result);
68 }
69 result.add(entry.getValue().build(entry.getKey(), databaseName, protocolType, dataSources, result, instanceContext));
70 }
71 return result;
72 }
73
74
75
76
77
78
79
80
81
82
83
84
85 @SuppressWarnings({"unchecked", "rawtypes"})
86 public static Collection<ShardingSphereRule> build(final String databaseName, final DatabaseType protocolType, final Map<String, DataSource> dataSources,
87 final Collection<ShardingSphereRule> rules, final RuleConfiguration ruleConfig, final InstanceContext instanceContext) {
88 Collection<ShardingSphereRule> result = new LinkedList<>();
89 for (Entry<RuleConfiguration, DatabaseRuleBuilder> entry : OrderedSPILoader.getServices(DatabaseRuleBuilder.class,
90 Collections.singletonList(ruleConfig), Comparator.reverseOrder()).entrySet()) {
91 RuleConfigurationChecker configChecker = OrderedSPILoader.getServicesByClass(
92 RuleConfigurationChecker.class, Collections.singleton(entry.getKey().getClass())).get(entry.getKey().getClass());
93 if (null != configChecker) {
94 configChecker.check(databaseName, entry.getKey(), dataSources, rules);
95 }
96 result.add(entry.getValue().build(entry.getKey(), databaseName, protocolType, dataSources, rules, instanceContext));
97 }
98 return result;
99 }
100
101 @SuppressWarnings("rawtypes")
102 private static Map<RuleConfiguration, DatabaseRuleBuilder> getRuleBuilderMap(final DatabaseConfiguration databaseConfig) {
103 Map<RuleConfiguration, DatabaseRuleBuilder> result = new LinkedHashMap<>();
104 result.putAll(getDistributedRuleBuilderMap(databaseConfig.getRuleConfigurations()));
105 result.putAll(getEnhancedRuleBuilderMap(databaseConfig.getRuleConfigurations()));
106 result.putAll(getMissedDefaultRuleBuilderMap(result.values()));
107 return result;
108 }
109
110 @SuppressWarnings("rawtypes")
111 private static Map<RuleConfiguration, DatabaseRuleBuilder> getDistributedRuleBuilderMap(final Collection<RuleConfiguration> ruleConfigs) {
112 Collection<RuleConfiguration> distributedRuleConfigs = ruleConfigs.stream().filter(each -> isAssignableFrom(each, DistributedRuleConfiguration.class)).collect(Collectors.toList());
113 return OrderedSPILoader.getServices(DatabaseRuleBuilder.class, distributedRuleConfigs, Comparator.reverseOrder());
114 }
115
116 @SuppressWarnings("rawtypes")
117 private static Map<RuleConfiguration, DatabaseRuleBuilder> getEnhancedRuleBuilderMap(final Collection<RuleConfiguration> ruleConfigs) {
118 Collection<RuleConfiguration> enhancedRuleConfigs = ruleConfigs.stream().filter(each -> isAssignableFrom(each, EnhancedRuleConfiguration.class)).collect(Collectors.toList());
119 return OrderedSPILoader.getServices(DatabaseRuleBuilder.class, enhancedRuleConfigs);
120 }
121
122 private static boolean isAssignableFrom(final RuleConfiguration ruleConfig, final Class<? extends RuleConfiguration> ruleConfigClass) {
123 return Arrays.stream(ruleConfig.getClass().getInterfaces()).anyMatch(ruleConfigClass::isAssignableFrom);
124 }
125
126 @SuppressWarnings("rawtypes")
127 private static Map<RuleConfiguration, DatabaseRuleBuilder> getMissedDefaultRuleBuilderMap(final Collection<DatabaseRuleBuilder> configuredBuilders) {
128 Map<RuleConfiguration, DatabaseRuleBuilder> result = new LinkedHashMap<>();
129 Map<DatabaseRuleBuilder, DefaultDatabaseRuleConfigurationBuilder> defaultBuilders =
130 OrderedSPILoader.getServices(DefaultDatabaseRuleConfigurationBuilder.class, getMissedDefaultRuleBuilders(configuredBuilders));
131
132 for (Entry<DatabaseRuleBuilder, DefaultDatabaseRuleConfigurationBuilder> entry : defaultBuilders.entrySet()) {
133 result.put(entry.getValue().build(), entry.getKey());
134 }
135 return result;
136 }
137
138 @SuppressWarnings({"unchecked", "rawtypes"})
139 private static Collection<DatabaseRuleBuilder> getMissedDefaultRuleBuilders(final Collection<DatabaseRuleBuilder> configuredBuilders) {
140 Collection<Class<DatabaseRuleBuilder>> configuredBuilderClasses = configuredBuilders.stream().map(each -> (Class<DatabaseRuleBuilder>) each.getClass()).collect(Collectors.toSet());
141 return OrderedSPILoader.getServices(DatabaseRuleBuilder.class).stream().filter(each -> !configuredBuilderClasses.contains(each.getClass())).collect(Collectors.toList());
142 }
143 }