PrimaryReplicaReplicationSQLRouter implements SQLRouter<PrimaryReplicaReplicationRule> { @Override public void decorateRouteContext(final RouteContext routeContext, final LogicSQL logicSQL, final PrimaryReplicaReplicationRule rule, final ConfigurationProperties props) { Collection<RouteUnit> toBeRemoved = new LinkedList<>(); Collection<RouteUnit> toBeAdded = new LinkedList<>(); for (RouteUnit each : routeContext.getRouteUnits()) { String dataSourceName = each.getDataSourceMapper().getLogicName(); Optional<PrimaryReplicaReplicationDataSourceRule> dataSourceRule = rule.findDataSourceRule(dataSourceName); if (dataSourceRule.isPresent() && dataSourceRule.get().getName().equalsIgnoreCase(each.getDataSourceMapper().getActualName())) { toBeRemoved.add(each); String actualDataSourceName = new PrimaryReplicaReplicationDataSourceRouter(dataSourceRule.get()).route(logicSQL.getSqlStatementContext().getSqlStatement()); toBeAdded.add(new RouteUnit(new RouteMapper(each.getDataSourceMapper().getLogicName(), actualDataSourceName), each.getTableMappers())); } } routeContext.getRouteUnits().removeAll(toBeRemoved); routeContext.getRouteUnits().addAll(toBeAdded); }  @Override RouteContext createRouteContext(final LogicSQL logicSQL, final PrimaryReplicaReplicationRule rule, final ConfigurationProperties props); @Override void decorateRouteContext(final RouteContext routeContext, final LogicSQL logicSQL, final PrimaryReplicaReplicationRule rule, final ConfigurationProperties props); @Override int getOrder(); @Override Class<PrimaryReplicaReplicationRule> getTypeClass();  }
@Test public void assertDecorateRouteContextToPrimaryDataSource() { RouteContext actual = mockRouteContext(); ShardingSphereSchema schema = new ShardingSphereSchema("logic_schema", Collections.emptyList(), Collections.singleton(rule), Collections.emptyMap(), mock(ShardingSphereMetaData.class)); LogicSQL logicSQL = new LogicSQL(schema, mock(SQLStatementContext.class), "", Collections.emptyList()); sqlRouter.decorateRouteContext(actual, logicSQL, rule, new ConfigurationProperties(new Properties())); Iterator<String> routedDataSourceNames = actual.getActualDataSourceNames().iterator(); assertThat(routedDataSourceNames.next(), is(NON_PRIMARY_REPLICA_DATASOURCE_NAME)); assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE)); }
@Test public void assertDecorateRouteContextToReplicaDataSource() { RouteContext actual = mockRouteContext(); MySQLSelectStatement selectStatement = mock(MySQLSelectStatement.class); when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement); when(selectStatement.getLock()).thenReturn(Optional.empty()); ShardingSphereSchema schema = new ShardingSphereSchema("logic_schema", Collections.emptyList(), Collections.singleton(rule), Collections.emptyMap(), mock(ShardingSphereMetaData.class)); LogicSQL logicSQL = new LogicSQL(schema, sqlStatementContext, "", Collections.emptyList()); sqlRouter.decorateRouteContext(actual, logicSQL, rule, new ConfigurationProperties(new Properties())); Iterator<String> routedDataSourceNames = actual.getActualDataSourceNames().iterator(); assertThat(routedDataSourceNames.next(), is(NON_PRIMARY_REPLICA_DATASOURCE_NAME)); assertThat(routedDataSourceNames.next(), is(REPLICA_DATASOURCE)); }
@Test public void assertDecorateRouteContextToPrimaryDataSourceWithLock() { RouteContext actual = mockRouteContext(); MySQLSelectStatement selectStatement = mock(MySQLSelectStatement.class); when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement); when(selectStatement.getLock()).thenReturn(Optional.of(mock(LockSegment.class))); ShardingSphereSchema schema = new ShardingSphereSchema("logic_schema", Collections.emptyList(), Collections.singleton(rule), Collections.emptyMap(), mock(ShardingSphereMetaData.class)); LogicSQL logicSQL = new LogicSQL(schema, sqlStatementContext, "", Collections.emptyList()); sqlRouter.decorateRouteContext(actual, logicSQL, rule, new ConfigurationProperties(new Properties())); Iterator<String> routedDataSourceNames = actual.getActualDataSourceNames().iterator(); assertThat(routedDataSourceNames.next(), is(NON_PRIMARY_REPLICA_DATASOURCE_NAME)); assertThat(routedDataSourceNames.next(), is(PRIMARY_DATASOURCE)); }