1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.shadow.route;
19
20 import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
21 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
22 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
23 import org.apache.shardingsphere.infra.route.context.RouteContext;
24 import org.apache.shardingsphere.infra.route.context.RouteMapper;
25 import org.apache.shardingsphere.infra.route.context.RouteUnit;
26 import org.apache.shardingsphere.infra.route.lifecycle.DecorateSQLRouter;
27 import org.apache.shardingsphere.infra.session.query.QueryContext;
28 import org.apache.shardingsphere.shadow.constant.ShadowOrder;
29 import org.apache.shardingsphere.shadow.route.retriever.ShadowDataSourceMappingsRetrieverFactory;
30 import org.apache.shardingsphere.shadow.rule.ShadowRule;
31
32 import java.util.Collection;
33 import java.util.LinkedList;
34 import java.util.Map;
35 import java.util.Optional;
36
37
38
39
40 @HighFrequencyInvocation
41 public final class ShadowSQLRouter implements DecorateSQLRouter<ShadowRule> {
42
43 @Override
44 public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database,
45 final ShadowRule rule, final Collection<String> tableNames, final ConfigurationProperties props) {
46 Collection<RouteUnit> toBeRemovedRouteUnit = new LinkedList<>();
47 Collection<RouteUnit> toBeAddedRouteUnit = new LinkedList<>();
48 Map<String, String> shadowDataSourceMappings = ShadowDataSourceMappingsRetrieverFactory.newInstance(queryContext).retrieve(rule);
49 for (RouteUnit each : routeContext.getRouteUnits()) {
50 String logicName = each.getDataSourceMapper().getLogicName();
51 String actualName = each.getDataSourceMapper().getActualName();
52 Optional<String> productionDataSourceName = rule.findProductionDataSourceName(actualName);
53 if (productionDataSourceName.isPresent()) {
54 String shadowDataSourceName = shadowDataSourceMappings.get(productionDataSourceName.get());
55 toBeRemovedRouteUnit.add(each);
56 String dataSourceName = null == shadowDataSourceName ? productionDataSourceName.get() : shadowDataSourceName;
57 toBeAddedRouteUnit.add(new RouteUnit(new RouteMapper(logicName, dataSourceName), each.getTableMappers()));
58 }
59 }
60 routeContext.getRouteUnits().removeAll(toBeRemovedRouteUnit);
61 routeContext.getRouteUnits().addAll(toBeAddedRouteUnit);
62 }
63
64 @Override
65 public Type getType() {
66 return Type.DATA_SOURCE;
67 }
68
69 @Override
70 public int getOrder() {
71 return ShadowOrder.ORDER;
72 }
73
74 @Override
75 public Class<ShadowRule> getTypeClass() {
76 return ShadowRule.class;
77 }
78 }