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.DatabaseRuleConfigurationChecker;
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.ComputeNodeInstanceContext;
29 import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
30 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
31 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
32
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
59 @SuppressWarnings({"unchecked", "rawtypes"})
60 public static Collection<ShardingSphereRule> build(final String databaseName, final DatabaseType protocolType, final DatabaseConfiguration databaseConfig,
61 final ComputeNodeInstanceContext computeNodeInstanceContext, final ResourceMetaData resourceMetaData) {
62 Collection<ShardingSphereRule> result = new LinkedList<>();
63 for (Entry<RuleConfiguration, DatabaseRuleBuilder> entry : getRuleBuilderMap(databaseConfig).entrySet()) {
64 DatabaseRuleConfigurationChecker configChecker = OrderedSPILoader.getServicesByClass(
65 DatabaseRuleConfigurationChecker.class, Collections.singleton(entry.getKey().getClass())).get(entry.getKey().getClass());
66 if (null != configChecker) {
67 configChecker.check(databaseName, entry.getKey(), resourceMetaData.getDataSourceMap(), result);
68 }
69 result.add(entry.getValue().build(entry.getKey(), databaseName, protocolType, resourceMetaData, result, computeNodeInstanceContext));
70 }
71 return result;
72 }
73
74
75
76
77
78
79
80
81
82
83
84
85 @SuppressWarnings({"unchecked", "rawtypes"})
86 public static ShardingSphereRule build(final String databaseName, final DatabaseType protocolType, final Collection<ShardingSphereRule> rules, final RuleConfiguration ruleConfig,
87 final ComputeNodeInstanceContext computeNodeInstanceContext, final ResourceMetaData resourceMetaData) {
88 DatabaseRuleBuilder databaseRuleBuilder = OrderedSPILoader.getServices(DatabaseRuleBuilder.class, Collections.singleton(ruleConfig)).get(ruleConfig);
89 DatabaseRuleConfigurationChecker configChecker =
90 OrderedSPILoader.getServicesByClass(DatabaseRuleConfigurationChecker.class, Collections.singleton(ruleConfig.getClass())).get(ruleConfig.getClass());
91 if (null != configChecker) {
92 configChecker.check(databaseName, ruleConfig, resourceMetaData.getDataSourceMap(), rules);
93 }
94 return databaseRuleBuilder.build(ruleConfig, databaseName, protocolType, resourceMetaData, rules, computeNodeInstanceContext);
95 }
96
97 @SuppressWarnings("rawtypes")
98 private static Map<RuleConfiguration, DatabaseRuleBuilder> getRuleBuilderMap(final DatabaseConfiguration databaseConfig) {
99 Map<RuleConfiguration, DatabaseRuleBuilder> result = new LinkedHashMap<>();
100 result.putAll(getDistributedRuleBuilderMap(databaseConfig.getRuleConfigurations()));
101 result.putAll(getEnhancedRuleBuilderMap(databaseConfig.getRuleConfigurations()));
102 result.putAll(getMissedDefaultRuleBuilderMap(result.values()));
103 return result;
104 }
105
106 @SuppressWarnings("rawtypes")
107 private static Map<RuleConfiguration, DatabaseRuleBuilder> getDistributedRuleBuilderMap(final Collection<RuleConfiguration> ruleConfigs) {
108 Collection<RuleConfiguration> distributedRuleConfigs = ruleConfigs.stream().filter(each -> isAssignableFrom(each, DistributedRuleConfiguration.class)).collect(Collectors.toList());
109 return OrderedSPILoader.getServices(DatabaseRuleBuilder.class, distributedRuleConfigs, Comparator.reverseOrder());
110 }
111
112 @SuppressWarnings("rawtypes")
113 private static Map<RuleConfiguration, DatabaseRuleBuilder> getEnhancedRuleBuilderMap(final Collection<RuleConfiguration> ruleConfigs) {
114 Collection<RuleConfiguration> enhancedRuleConfigs = ruleConfigs.stream().filter(each -> isAssignableFrom(each, EnhancedRuleConfiguration.class)).collect(Collectors.toList());
115 return OrderedSPILoader.getServices(DatabaseRuleBuilder.class, enhancedRuleConfigs);
116 }
117
118 private static boolean isAssignableFrom(final RuleConfiguration ruleConfig, final Class<? extends RuleConfiguration> ruleConfigClass) {
119 return Arrays.stream(ruleConfig.getClass().getInterfaces()).anyMatch(ruleConfigClass::isAssignableFrom);
120 }
121
122 @SuppressWarnings("rawtypes")
123 private static Map<RuleConfiguration, DatabaseRuleBuilder> getMissedDefaultRuleBuilderMap(final Collection<DatabaseRuleBuilder> configuredBuilders) {
124 Map<RuleConfiguration, DatabaseRuleBuilder> result = new LinkedHashMap<>();
125 Map<DatabaseRuleBuilder, DefaultDatabaseRuleConfigurationBuilder> defaultBuilders =
126 OrderedSPILoader.getServices(DefaultDatabaseRuleConfigurationBuilder.class, getMissedDefaultRuleBuilders(configuredBuilders));
127
128 for (Entry<DatabaseRuleBuilder, DefaultDatabaseRuleConfigurationBuilder> entry : defaultBuilders.entrySet()) {
129 result.put(entry.getValue().build(), entry.getKey());
130 }
131 return result;
132 }
133
134 @SuppressWarnings({"unchecked", "rawtypes"})
135 private static Collection<DatabaseRuleBuilder> getMissedDefaultRuleBuilders(final Collection<DatabaseRuleBuilder> configuredBuilders) {
136 Collection<Class<DatabaseRuleBuilder>> configuredBuilderClasses = configuredBuilders.stream().map(each -> (Class<DatabaseRuleBuilder>) each.getClass()).collect(Collectors.toSet());
137 return OrderedSPILoader.getServices(DatabaseRuleBuilder.class).stream().filter(each -> !configuredBuilderClasses.contains(each.getClass())).collect(Collectors.toList());
138 }
139 }