From f1af66a290effa3cea70345244e1ac01b6218c62 Mon Sep 17 00:00:00 2001 From: Liang Zhang Date: Wed, 3 Jul 2024 00:00:02 +0800 Subject: [PATCH] Spilt SQLRouter to EntranceSQLRouter and DecorateSQLRouter (#31962) * Remove useless dependencies declarations for feature pom * Add TableAggregationSQLRouter * Add TableAggregationSQLRouter * Add DecorateSQLRouter * Add DecorateSQLRouter --- .../PostgreSQLParserStatementExample.java | 2 +- .../broadcast/route/BroadcastSQLRouter.java | 5 +- .../route/ReadwriteSplittingSQLRouter.java | 16 +-- .../ReadwriteSplittingSQLRouterTest.java | 107 ------------------ .../shadow/route/ShadowSQLRouter.java | 12 +- .../route/engine/ShardingSQLRouter.java | 10 +- .../infra/route/DecorateSQLRouter.java | 39 ++++--- .../infra/route/EntranceSQLRouter.java | 48 ++++++++ .../shardingsphere/infra/route/SQLRouter.java | 32 ------ .../engine/impl/PartialSQLRouteExecutor.java | 12 +- .../router/SQLRouterFailureFixture.java | 15 +-- .../fixture/router/SQLRouterFixture.java | 9 +- .../single/route/SingleSQLRouter.java | 5 +- 13 files changed, 99 insertions(+), 213 deletions(-) rename features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouterTest.java => infra/route/src/main/java/org/apache/shardingsphere/infra/route/DecorateSQLRouter.java (57%) create mode 100644 infra/route/src/main/java/org/apache/shardingsphere/infra/route/EntranceSQLRouter.java diff --git a/examples/shardingsphere-parser-example/src/main/java/org/apache/shardingsphere/example/parser/postgresql/statement/PostgreSQLParserStatementExample.java b/examples/shardingsphere-parser-example/src/main/java/org/apache/shardingsphere/example/parser/postgresql/statement/PostgreSQLParserStatementExample.java index c9d24ba6aab1d..4c9cc230828c6 100644 --- a/examples/shardingsphere-parser-example/src/main/java/org/apache/shardingsphere/example/parser/postgresql/statement/PostgreSQLParserStatementExample.java +++ b/examples/shardingsphere-parser-example/src/main/java/org/apache/shardingsphere/example/parser/postgresql/statement/PostgreSQLParserStatementExample.java @@ -21,7 +21,7 @@ import org.apache.shardingsphere.sql.parser.api.SQLParserEngine; import org.apache.shardingsphere.sql.parser.api.SQLStatementVisitorEngine; import org.apache.shardingsphere.sql.parser.core.ParseASTNode; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.statement.SQLStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; import java.util.Arrays; import java.util.List; diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java index 283021fd6d33a..e34b5f983b4d5 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java @@ -29,7 +29,8 @@ import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; +import org.apache.shardingsphere.infra.route.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; @@ -61,7 +62,7 @@ * Broadcast SQL router. */ @HighFrequencyInvocation -public final class BroadcastSQLRouter implements SQLRouter { +public final class BroadcastSQLRouter implements EntranceSQLRouter, DecorateSQLRouter { @Override public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java index 9c59e54b29af6..120552ba9d920 100644 --- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java +++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouter.java @@ -20,8 +20,7 @@ import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; @@ -32,7 +31,6 @@ import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule; import java.util.Collection; -import java.util.Collections; import java.util.LinkedList; import java.util.Optional; @@ -40,17 +38,7 @@ * Readwrite-splitting SQL router. */ @HighFrequencyInvocation -public final class ReadwriteSplittingSQLRouter implements SQLRouter { - - @Override - public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, - final ShardingSphereDatabase database, final ReadwriteSplittingRule rule, final ConfigurationProperties props, final ConnectionContext connectionContext) { - RouteContext result = new RouteContext(); - ReadwriteSplittingDataSourceGroupRule dataSourceGroupRule = rule.getSingleDataSourceGroupRule(); - String dataSourceName = new ReadwriteSplittingDataSourceRouter(dataSourceGroupRule, connectionContext).route(queryContext.getSqlStatementContext(), queryContext.getHintValueContext()); - result.getRouteUnits().add(new RouteUnit(new RouteMapper(dataSourceGroupRule.getName(), dataSourceName), Collections.emptyList())); - return result; - } +public final class ReadwriteSplittingSQLRouter implements DecorateSQLRouter { @Override public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database, diff --git a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java index 9708ffd5ed93d..aa25e6f850cff 100644 --- a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java +++ b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java @@ -19,7 +19,6 @@ import org.apache.shardingsphere.infra.binder.context.statement.CommonSQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.database.core.DefaultDatabase; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; @@ -39,9 +38,6 @@ import org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration; import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.LockSegment; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.InsertStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; -import org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLInsertStatement; import org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -85,22 +81,6 @@ void setUp() { sqlRouter = (ReadwriteSplittingSQLRouter) OrderedSPILoader.getServices(SQLRouter.class, Collections.singleton(staticRule)).get(staticRule); } - @Test - void assertCreateRouteContextToPrimaryWithoutRouteUnits() { - QueryContext queryContext = new QueryContext(mock(SQLStatementContext.class), "", Collections.emptyList(), new HintValueContext()); - RuleMetaData ruleMetaData = new RuleMetaData(Collections.singleton(staticRule)); - ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, - mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, Collections.emptyMap()); - RouteContext actual = sqlRouter.createRouteContext(queryContext, - mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - assertThat(actual.getRouteUnits().size(), is(1)); - RouteUnit routeUnit = actual.getRouteUnits().iterator().next(); - assertThat(routeUnit.getDataSourceMapper().getLogicName(), is(DATASOURCE_NAME)); - assertThat(routeUnit.getDataSourceMapper().getActualName(), is(WRITE_DATASOURCE)); - Iterator routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); - } - @Test void assertDecorateRouteContextToPrimaryDataSource() { RouteContext actual = mockRouteContext(); @@ -114,25 +94,6 @@ void assertDecorateRouteContextToPrimaryDataSource() { assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); } - @Test - void assertCreateRouteContextToReplicaDataSource() { - MySQLSelectStatement selectStatement = mock(MySQLSelectStatement.class); - when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement); - when(selectStatement.getLock()).thenReturn(Optional.empty()); - QueryContext queryContext = new QueryContext(sqlStatementContext, "", Collections.emptyList(), new HintValueContext()); - RuleMetaData ruleMetaData = new RuleMetaData(Collections.singleton(staticRule)); - ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, - mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, Collections.emptyMap()); - RouteContext actual = sqlRouter.createRouteContext(queryContext, - mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - assertThat(actual.getRouteUnits().size(), is(1)); - RouteUnit routeUnit = actual.getRouteUnits().iterator().next(); - assertThat(routeUnit.getDataSourceMapper().getLogicName(), is(DATASOURCE_NAME)); - assertThat(routeUnit.getDataSourceMapper().getActualName(), is(READ_DATASOURCE)); - Iterator routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(READ_DATASOURCE)); - } - @Test void assertDecorateRouteContextToReplicaDataSource() { RouteContext actual = mockRouteContext(); @@ -149,21 +110,6 @@ void assertDecorateRouteContextToReplicaDataSource() { assertThat(routedDataSourceNames.next(), is(READ_DATASOURCE)); } - @Test - void assertCreateRouteContextToPrimaryDataSourceWithLock() { - MySQLSelectStatement selectStatement = mock(MySQLSelectStatement.class); - when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement); - when(selectStatement.getLock()).thenReturn(Optional.of(mock(LockSegment.class))); - QueryContext queryContext = new QueryContext(sqlStatementContext, "", Collections.emptyList(), new HintValueContext()); - RuleMetaData ruleMetaData = new RuleMetaData(Collections.singleton(staticRule)); - ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, - mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, Collections.emptyMap()); - RouteContext actual = sqlRouter.createRouteContext(queryContext, - mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - Iterator routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); - } - @Test void assertDecorateRouteContextToPrimaryDataSourceWithLock() { RouteContext actual = mockRouteContext(); @@ -180,59 +126,6 @@ void assertDecorateRouteContextToPrimaryDataSourceWithLock() { assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); } - @Test - void assertCreateRouteContextToPrimaryDataSource() { - when(sqlStatementContext.getSqlStatement()).thenReturn(mock(InsertStatement.class)); - QueryContext queryContext = new QueryContext(sqlStatementContext, "", Collections.emptyList(), new HintValueContext()); - RuleMetaData ruleMetaData = new RuleMetaData(Collections.singleton(staticRule)); - ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, - mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, Collections.emptyMap()); - RouteContext actual = sqlRouter.createRouteContext(queryContext, - mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - Iterator routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); - } - - @Test - void assertCreateRouteContextToReadDataSource() { - MySQLInsertStatement insertStatement = mock(MySQLInsertStatement.class); - when(sqlStatementContext.getSqlStatement()).thenReturn(insertStatement); - QueryContext queryContext = new QueryContext(sqlStatementContext, "", Collections.emptyList(), new HintValueContext()); - RuleMetaData ruleMetaData = new RuleMetaData(Collections.singleton(staticRule)); - ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, - mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, Collections.emptyMap()); - RouteContext actual = sqlRouter.createRouteContext(queryContext, - mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - Iterator routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); - MySQLSelectStatement selectStatement = mock(MySQLSelectStatement.class); - when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement); - when(selectStatement.getLock()).thenReturn(Optional.empty()); - queryContext = new QueryContext(sqlStatementContext, "", Collections.emptyList(), new HintValueContext()); - actual = sqlRouter.createRouteContext( - queryContext, mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(READ_DATASOURCE)); - } - - @Test - void assertSqlHintRouteWriteOnly() { - SelectStatement statement = mock(SelectStatement.class); - SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(sqlStatementContext.getSqlStatement()).thenReturn(statement); - HintValueContext hintValueContext = mock(HintValueContext.class); - when(hintValueContext.isWriteRouteOnly()).thenReturn(true); - when(sqlStatementContext.getProjectionsContext().isContainsLastInsertIdProjection()).thenReturn(false); - QueryContext queryContext = new QueryContext(sqlStatementContext, "", Collections.emptyList(), hintValueContext); - RuleMetaData ruleMetaData = new RuleMetaData(Collections.singleton(staticRule)); - ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, - mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, Collections.emptyMap()); - RouteContext actual = sqlRouter.createRouteContext(queryContext, - mock(RuleMetaData.class), database, staticRule, new ConfigurationProperties(new Properties()), new ConnectionContext(Collections::emptySet)); - Iterator routedDataSourceNames = actual.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is(WRITE_DATASOURCE)); - } - private RouteContext mockRouteContext() { RouteContext result = new RouteContext(); RouteUnit routeUnit = new RouteUnit(new RouteMapper(DATASOURCE_NAME, DATASOURCE_NAME), Collections.singleton(new RouteMapper("table", "table_0"))); diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouter.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouter.java index 18b08f2870528..442465bcd9f50 100644 --- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouter.java +++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouter.java @@ -20,8 +20,7 @@ import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.session.query.QueryContext; @@ -33,14 +32,7 @@ * Shadow SQL router. */ @HighFrequencyInvocation -public final class ShadowSQLRouter implements SQLRouter { - - @Override - public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, - final ShadowRule rule, final ConfigurationProperties props, final ConnectionContext connectionContext) { - // TODO - return new RouteContext(); - } +public final class ShadowSQLRouter implements DecorateSQLRouter { @Override public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database, diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/ShardingSQLRouter.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/ShardingSQLRouter.java index e53fda6f0e8e8..897f6b39be44e 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/ShardingSQLRouter.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/ShardingSQLRouter.java @@ -22,7 +22,7 @@ import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.session.query.QueryContext; @@ -46,7 +46,7 @@ * Sharding SQL router. */ @HighFrequencyInvocation -public final class ShardingSQLRouter implements SQLRouter { +public final class ShardingSQLRouter implements EntranceSQLRouter { @Override public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, final ShardingRule rule, @@ -86,12 +86,6 @@ private ShardingConditions createShardingConditions(final QueryContext queryCont return new ShardingConditions(shardingConditions, queryContext.getSqlStatementContext(), rule); } - @Override - public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database, final ShardingRule rule, - final ConfigurationProperties props, final ConnectionContext connectionContext) { - // TODO - } - @Override public int getOrder() { return ShardingOrder.ORDER; diff --git a/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouterTest.java b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/DecorateSQLRouter.java similarity index 57% rename from features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouterTest.java rename to infra/route/src/main/java/org/apache/shardingsphere/infra/route/DecorateSQLRouter.java index 8f7dcfc198a90..d4a95581fe3ab 100644 --- a/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/route/ShadowSQLRouterTest.java +++ b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/DecorateSQLRouter.java @@ -15,26 +15,31 @@ * limitations under the License. */ -package org.apache.shardingsphere.shadow.route; +package org.apache.shardingsphere.infra.route; -import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; -import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.shadow.rule.ShadowRule; -import org.junit.jupiter.api.Test; - -import java.util.Collections; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.mock; +import org.apache.shardingsphere.infra.route.context.RouteContext; +import org.apache.shardingsphere.infra.rule.ShardingSphereRule; +import org.apache.shardingsphere.infra.session.connection.ConnectionContext; +import org.apache.shardingsphere.infra.session.query.QueryContext; -class ShadowSQLRouterTest { +/** + * Decorate SQL Router. + * + * @param type of rule + */ +public interface DecorateSQLRouter extends SQLRouter { - @Test - void assertCreateRouteContext() { - assertNotNull(new ShadowSQLRouter().createRouteContext(mock(QueryContext.class), - mock(RuleMetaData.class), mock(ShardingSphereDatabase.class), mock(ShadowRule.class), mock(ConfigurationProperties.class), new ConnectionContext(Collections::emptySet))); - } + /** + * Decorate route context. + * + * @param routeContext route context + * @param queryContext query context + * @param database database + * @param rule rule + * @param props configuration properties + * @param connectionContext connection context + */ + void decorateRouteContext(RouteContext routeContext, QueryContext queryContext, ShardingSphereDatabase database, T rule, ConfigurationProperties props, ConnectionContext connectionContext); } diff --git a/infra/route/src/main/java/org/apache/shardingsphere/infra/route/EntranceSQLRouter.java b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/EntranceSQLRouter.java new file mode 100644 index 0000000000000..894c74ed2f4aa --- /dev/null +++ b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/EntranceSQLRouter.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.route; + +import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; +import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; +import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; +import org.apache.shardingsphere.infra.route.context.RouteContext; +import org.apache.shardingsphere.infra.rule.ShardingSphereRule; +import org.apache.shardingsphere.infra.session.connection.ConnectionContext; +import org.apache.shardingsphere.infra.session.query.QueryContext; + +/** + * Entrance SQL Router. + * + * @param type of rule + */ +public interface EntranceSQLRouter extends SQLRouter { + + /** + * Create route context. + * + * @param queryContext query context + * @param globalRuleMetaData global rule meta data + * @param database database + * @param rule rule + * @param props configuration properties + * @param connectionContext connection context + * @return route context + */ + RouteContext createRouteContext(QueryContext queryContext, + RuleMetaData globalRuleMetaData, ShardingSphereDatabase database, T rule, ConfigurationProperties props, ConnectionContext connectionContext); +} diff --git a/infra/route/src/main/java/org/apache/shardingsphere/infra/route/SQLRouter.java b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/SQLRouter.java index 385ea615904fa..bdc408773d254 100644 --- a/infra/route/src/main/java/org/apache/shardingsphere/infra/route/SQLRouter.java +++ b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/SQLRouter.java @@ -17,12 +17,6 @@ package org.apache.shardingsphere.infra.route; -import org.apache.shardingsphere.infra.session.query.QueryContext; -import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; -import org.apache.shardingsphere.infra.session.connection.ConnectionContext; -import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.rule.ShardingSphereRule; import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI; import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPI; @@ -34,30 +28,4 @@ */ @SingletonSPI public interface SQLRouter extends OrderedSPI { - - /** - * Create route context. - * - * @param queryContext query context - * @param globalRuleMetaData global rule meta data - * @param database database - * @param rule rule - * @param props configuration properties - * @param connectionContext connection context - * @return route context - */ - RouteContext createRouteContext(QueryContext queryContext, - RuleMetaData globalRuleMetaData, ShardingSphereDatabase database, T rule, ConfigurationProperties props, ConnectionContext connectionContext); - - /** - * Decorate route context. - * - * @param routeContext route context - * @param queryContext query context - * @param database database - * @param rule rule - * @param props configuration properties - * @param connectionContext connection context - */ - void decorateRouteContext(RouteContext routeContext, QueryContext queryContext, ShardingSphereDatabase database, T rule, ConfigurationProperties props, ConnectionContext connectionContext); } diff --git a/infra/route/src/main/java/org/apache/shardingsphere/infra/route/engine/impl/PartialSQLRouteExecutor.java b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/engine/impl/PartialSQLRouteExecutor.java index efd7dead93bb0..f7ac253025fe3 100644 --- a/infra/route/src/main/java/org/apache/shardingsphere/infra/route/engine/impl/PartialSQLRouteExecutor.java +++ b/infra/route/src/main/java/org/apache/shardingsphere/infra/route/engine/impl/PartialSQLRouteExecutor.java @@ -19,13 +19,15 @@ import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; +import org.apache.shardingsphere.infra.exception.kernel.syntax.hint.DataSourceHintNotExistsException; import org.apache.shardingsphere.infra.hint.HintManager; import org.apache.shardingsphere.infra.hint.HintValueContext; -import org.apache.shardingsphere.infra.exception.kernel.syntax.hint.DataSourceHintNotExistsException; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; @@ -67,10 +69,10 @@ public RouteContext route(final ConnectionContext connectionContext, final Query return result; } for (Entry entry : routers.entrySet()) { - if (result.getRouteUnits().isEmpty()) { - result = entry.getValue().createRouteContext(queryContext, globalRuleMetaData, database, entry.getKey(), props, connectionContext); - } else { - entry.getValue().decorateRouteContext(result, queryContext, database, entry.getKey(), props, connectionContext); + if (result.getRouteUnits().isEmpty() && entry.getValue() instanceof EntranceSQLRouter) { + result = ((EntranceSQLRouter) entry.getValue()).createRouteContext(queryContext, globalRuleMetaData, database, entry.getKey(), props, connectionContext); + } else if (entry.getValue() instanceof DecorateSQLRouter) { + ((DecorateSQLRouter) entry.getValue()).decorateRouteContext(result, queryContext, database, entry.getKey(), props, connectionContext); } } if (result.getRouteUnits().isEmpty() && 1 == database.getResourceMetaData().getStorageUnits().size()) { diff --git a/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFailureFixture.java b/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFailureFixture.java index 647a663c04960..70f6e1b6cc061 100644 --- a/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFailureFixture.java +++ b/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFailureFixture.java @@ -17,22 +17,15 @@ package org.apache.shardingsphere.infra.route.fixture.router; -import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; -import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.fixture.rule.RouteFailureRuleFixture; +import org.apache.shardingsphere.infra.session.connection.ConnectionContext; +import org.apache.shardingsphere.infra.session.query.QueryContext; -public final class SQLRouterFailureFixture implements SQLRouter { - - @Override - public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, - final RouteFailureRuleFixture rule, final ConfigurationProperties props, final ConnectionContext connectionContext) { - throw new UnsupportedOperationException("Route failure."); - } +public final class SQLRouterFailureFixture implements DecorateSQLRouter { @Override public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database, diff --git a/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFixture.java b/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFixture.java index a676a7359bf1c..60b7f8e7f16e7 100644 --- a/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFixture.java +++ b/infra/route/src/test/java/org/apache/shardingsphere/infra/route/fixture/router/SQLRouterFixture.java @@ -17,20 +17,21 @@ package org.apache.shardingsphere.infra.route.fixture.router; -import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; -import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; +import org.apache.shardingsphere.infra.route.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; import org.apache.shardingsphere.infra.route.fixture.rule.RouteRuleFixture; +import org.apache.shardingsphere.infra.session.connection.ConnectionContext; +import org.apache.shardingsphere.infra.session.query.QueryContext; import java.util.Collections; -public final class SQLRouterFixture implements SQLRouter { +public final class SQLRouterFixture implements EntranceSQLRouter, DecorateSQLRouter { @Override public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, final RouteRuleFixture rule, diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java index 7c6982d047d25..e65486e8bc9f3 100644 --- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java +++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java @@ -24,7 +24,8 @@ import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable; -import org.apache.shardingsphere.infra.route.SQLRouter; +import org.apache.shardingsphere.infra.route.DecorateSQLRouter; +import org.apache.shardingsphere.infra.route.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; @@ -44,7 +45,7 @@ * Single SQL router. */ @HighFrequencyInvocation -public final class SingleSQLRouter implements SQLRouter { +public final class SingleSQLRouter implements EntranceSQLRouter, DecorateSQLRouter { @Override public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, final SingleRule rule,