Skip to content

Commit

Permalink
Reuse one routeContext instance in decorator (#7621)
Browse files Browse the repository at this point in the history
* Reuse routeContext in decorator

* Remove dependencies of RouteContext's second constructor

* Change RouteDecorator.decorate to void

* Change UnconfiguredSchemaRouteDecorator.decorate to void

* Remove useless RouteContext's constructor
  • Loading branch information
terrymanu committed Sep 27, 2020
1 parent 71f57dd commit a239f0e
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 106 deletions.
Expand Up @@ -39,7 +39,7 @@
public final class ConsensusReplicationRouteDecorator implements RouteDecorator<ConsensusReplicationRule> {

@Override
public RouteContext decorate(final RouteContext routeContext, final ShardingSphereMetaData metaData, final ConsensusReplicationRule consensusReplicationRule, final ConfigurationProperties props) {
public void decorate(final RouteContext routeContext, final ShardingSphereMetaData metaData, final ConsensusReplicationRule consensusReplicationRule, final ConfigurationProperties props) {
Map<String, ConsensusReplicationGroup> replicaGroups = new HashMap<>();
String schemaName = metaData.getSchemaName();
SQLStatementContext<?> sqlStatementContext = routeContext.getSqlStatementContext();
Expand All @@ -48,8 +48,8 @@ public RouteContext decorate(final RouteContext routeContext, final ShardingSphe
ConsensusReplicationGroup replicaGroup = new ConsensusReplicationGroup(replicaRoutingRule.getPhysicsTable(), replicaRoutingRule.getReplicaGroupId(), replicaRoutingRule.getReplicaPeers(),
replicaRoutingRule.getDataSourceName());
replicaGroups.put(ConsensusReplicationGroup.BLANK_CONSENSUS_REPLICATION_GROUP_KEY, replicaGroup);
return new RouteContext(
routeContext, routeContext.getRouteResult(), new ConsensusReplicationRouteStageContext(schemaName, replicaGroups, sqlStatementContext.isReadOnly()), getTypeClass());
routeContext.addNextRouteStageContext(getTypeClass(), new ConsensusReplicationRouteStageContext(schemaName, replicaGroups, sqlStatementContext.isReadOnly()));
return;
}
for (RouteUnit each : routeContext.getRouteResult().getRouteUnits()) {
Collection<RouteMapper> routeMappers = each.getTableMappers();
Expand All @@ -62,7 +62,7 @@ public RouteContext decorate(final RouteContext routeContext, final ShardingSphe
routeReplicaGroups(routeMappers, consensusReplicationRule, replicaGroups);
}
}
return new RouteContext(routeContext, routeContext.getRouteResult(), new ConsensusReplicationRouteStageContext(schemaName, replicaGroups, sqlStatementContext.isReadOnly()), getTypeClass());
routeContext.addNextRouteStageContext(getTypeClass(), new ConsensusReplicationRouteStageContext(schemaName, replicaGroups, sqlStatementContext.isReadOnly()));
}

private void routeReplicaGroups(final Collection<RouteMapper> routeMappers, final ConsensusReplicationRule replicaRule, final Map<String, ConsensusReplicationGroup> replicaGroups) {
Expand Down
Expand Up @@ -23,7 +23,6 @@
import org.apache.shardingsphere.infra.route.context.DefaultRouteStageContext;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteMapper;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.infra.route.context.RouteUnit;
import org.apache.shardingsphere.infra.route.decorator.RouteDecorator;
import org.apache.shardingsphere.replication.primaryreplica.constant.PrimaryReplicaReplicationOrder;
Expand All @@ -42,12 +41,12 @@
public final class PrimaryReplicaReplicationRouteDecorator implements RouteDecorator<PrimaryReplicaReplicationRule> {

@Override
public RouteContext decorate(final RouteContext routeContext, final ShardingSphereMetaData metaData, final PrimaryReplicaReplicationRule rule, final ConfigurationProperties props) {
public void decorate(final RouteContext routeContext, final ShardingSphereMetaData metaData, final PrimaryReplicaReplicationRule rule, final ConfigurationProperties props) {
if (routeContext.getRouteResult().getRouteUnits().isEmpty()) {
String dataSourceName = new PrimaryReplicaReplicationDataSourceRouter(rule.getSingleDataSourceRule()).route(routeContext.getSqlStatementContext().getSqlStatement());
RouteResult routeResult = new RouteResult();
routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(DefaultSchema.LOGIC_NAME, dataSourceName), Collections.emptyList()));
return new RouteContext(routeContext, routeResult, new DefaultRouteStageContext(), getTypeClass());
routeContext.getRouteResult().getRouteUnits().add(new RouteUnit(new RouteMapper(DefaultSchema.LOGIC_NAME, dataSourceName), Collections.emptyList()));
routeContext.addNextRouteStageContext(getTypeClass(), new DefaultRouteStageContext());
return;
}
Collection<RouteUnit> toBeRemoved = new LinkedList<>();
Collection<RouteUnit> toBeAdded = new LinkedList<>();
Expand All @@ -62,7 +61,6 @@ public RouteContext decorate(final RouteContext routeContext, final ShardingSphe
}
routeContext.getRouteResult().getRouteUnits().removeAll(toBeRemoved);
routeContext.getRouteResult().getRouteUnits().addAll(toBeAdded);
return routeContext;
}

@Override
Expand Down
Expand Up @@ -94,79 +94,80 @@ public void tearDown() {

@Test
public void assertDecorateToPrimary() {
RouteContext routeContext = mockSQLRouteContext(insertStatement);
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
RouteContext actual = mockSQLRouteContext(insertStatement);
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(NON_PRIMARY_REPLICA_DATASOURCE_NAME));
assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE));
}

@Test
public void assertDecorateToPrimaryWithoutRouteUnits() {
RouteContext routeContext = mockSQLRouteContextWithoutRouteUnits(insertStatement);
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
RouteContext actual = mockSQLRouteContextWithoutRouteUnits(insertStatement);
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE));
}

@Test
public void assertDecorateToReplica() {
RouteContext routeContext = mockSQLRouteContext(selectStatement);
RouteContext actual = mockSQLRouteContext(selectStatement);
when(selectStatement.getLock()).thenReturn(Optional.empty());
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(NON_PRIMARY_REPLICA_DATASOURCE_NAME));
assertThat(routedDataSourceNames.next(), is(REPLICA_DATASOURCE));
}

@Test
public void assertDecorateToReplicaWithoutRouteUnits() {
RouteContext routeContext = mockSQLRouteContextWithoutRouteUnits(selectStatement);
RouteContext actual = mockSQLRouteContextWithoutRouteUnits(selectStatement);
when(selectStatement.getLock()).thenReturn(Optional.empty());
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(REPLICA_DATASOURCE));
}

@Test
public void assertLockDecorateToPrimary() {
RouteContext routeContext = mockSQLRouteContext(selectStatement);
RouteContext actual = mockSQLRouteContext(selectStatement);
when(selectStatement.getLock()).thenReturn(Optional.of(mock(LockSegment.class)));
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(NON_PRIMARY_REPLICA_DATASOURCE_NAME));
assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE));
}

@Test
public void assertLockDecorateToPrimaryWithoutRouteUnits() {
RouteContext routeContext = mockSQLRouteContextWithoutRouteUnits(selectStatement);
RouteContext actual = mockSQLRouteContextWithoutRouteUnits(selectStatement);
when(selectStatement.getLock()).thenReturn(Optional.of(mock(LockSegment.class)));
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE));
}

@Test
public void assertDecorateToPrimaryWithoutRouteUnitsAndWithParameters() {
RouteContext routeContext = mockSQLRouteContextWithoutRouteUnitsAndWithParameters(insertStatement);
RouteContext actual = routeDecorator.decorate(routeContext, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
RouteContext actual = mockSQLRouteContextWithoutRouteUnitsAndWithParameters(insertStatement);
routeDecorator.decorate(actual, mock(ShardingSphereMetaData.class), rule, new ConfigurationProperties(new Properties()));
Iterator<String> routedDataSourceNames = actual.getRouteResult().getActualDataSourceNames().iterator();
assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE));
assertThat(actual.getParameters().get(0), is("true"));
}

private RouteContext mockSQLRouteContext(final SQLStatement sqlStatement) {
when(sqlStatementContext.getSqlStatement()).thenReturn(sqlStatement);
return new RouteContext(new RouteContext(sqlStatementContext, Collections.emptyList()), mockRouteResult(), null, null);
RouteContext result = new RouteContext(sqlStatementContext, Collections.emptyList());
mockRouteResult(result.getRouteResult());
result.addNextRouteStageContext(null, null);
return result;
}

private RouteResult mockRouteResult() {
RouteResult result = new RouteResult();
private void mockRouteResult(final RouteResult routeResult) {
RouteUnit routeUnit = new RouteUnit(new RouteMapper(DATASOURCE_NAME, DATASOURCE_NAME), Collections.singletonList(new RouteMapper("table", "table_0")));
result.getRouteUnits().add(routeUnit);
result.getRouteUnits().add(new RouteUnit(new RouteMapper(NON_PRIMARY_REPLICA_DATASOURCE_NAME, NON_PRIMARY_REPLICA_DATASOURCE_NAME), Collections.emptyList()));
return result;
routeResult.getRouteUnits().add(routeUnit);
routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(NON_PRIMARY_REPLICA_DATASOURCE_NAME, NON_PRIMARY_REPLICA_DATASOURCE_NAME), Collections.emptyList()));
}

private RouteContext mockSQLRouteContextWithoutRouteUnits(final SQLStatement sqlStatement) {
Expand Down
Expand Up @@ -45,30 +45,35 @@
public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> {

@Override
public RouteContext decorate(final RouteContext routeContext, final ShardingSphereMetaData metaData, final ShadowRule shadowRule, final ConfigurationProperties props) {
return routeContext.getRouteResult().getRouteUnits().isEmpty() ? getRouteContext(routeContext, shadowRule) : getRouteContextWithRouteResult(routeContext, shadowRule);
public void decorate(final RouteContext routeContext, final ShardingSphereMetaData metaData, final ShadowRule shadowRule, final ConfigurationProperties props) {
if (routeContext.getRouteResult().getRouteUnits().isEmpty()) {
decorateRouteContext(routeContext, shadowRule);
return;
}
decorateRouteContextWithRouteResult(routeContext, shadowRule);
}

private RouteContext getRouteContext(final RouteContext routeContext, final ShadowRule shadowRule) {
private void decorateRouteContext(final RouteContext routeContext, final ShadowRule shadowRule) {
SQLStatementContext<?> sqlStatementContext = routeContext.getSqlStatementContext();
SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
RouteResult routeResult = new RouteResult();
RouteResult routeResult = routeContext.getRouteResult();
if (!(sqlStatement instanceof DMLStatement)) {
shadowRule.getShadowMappings().forEach((key, value) -> {
routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(key, key), Collections.emptyList()));
routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(value, value), Collections.emptyList()));
});
return new RouteContext(routeContext, routeResult, new DefaultRouteStageContext(), getTypeClass());
routeContext.addNextRouteStageContext(getTypeClass(), new DefaultRouteStageContext());
return;
}
if (isShadow(routeContext, shadowRule)) {
shadowRule.getShadowMappings().values().forEach(each -> routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())));
} else {
shadowRule.getShadowMappings().keySet().forEach(each -> routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())));
}
return new RouteContext(routeContext, routeResult, new DefaultRouteStageContext(), getTypeClass());
routeContext.addNextRouteStageContext(getTypeClass(), new DefaultRouteStageContext());
}

private RouteContext getRouteContextWithRouteResult(final RouteContext routeContext, final ShadowRule shadowRule) {
private void decorateRouteContextWithRouteResult(final RouteContext routeContext, final ShadowRule shadowRule) {
SQLStatement sqlStatement = routeContext.getSqlStatementContext().getSqlStatement();
Collection<RouteUnit> toBeAdded = new LinkedList<>();
if (!(sqlStatement instanceof DMLStatement)) {
Expand All @@ -77,7 +82,7 @@ private RouteContext getRouteContextWithRouteResult(final RouteContext routeCont
toBeAdded.add(new RouteUnit(new RouteMapper(each.getDataSourceMapper().getLogicName(), shadowDataSourceName), each.getTableMappers()));
}
routeContext.getRouteResult().getRouteUnits().addAll(toBeAdded);
return routeContext;
return;
}
Collection<RouteUnit> toBeRemoved = new LinkedList<>();
if (isShadow(routeContext, shadowRule)) {
Expand All @@ -89,7 +94,6 @@ private RouteContext getRouteContextWithRouteResult(final RouteContext routeCont
}
routeContext.getRouteResult().getRouteUnits().removeAll(toBeRemoved);
routeContext.getRouteResult().getRouteUnits().addAll(toBeAdded);
return routeContext;
}

private boolean isShadow(final RouteContext routeContext, final ShadowRule shadowRule) {
Expand Down

0 comments on commit a239f0e

Please sign in to comment.