From 4889b3eaaec7309879993bc626bc7f7e69226ce7 Mon Sep 17 00:00:00 2001 From: Liang Zhang Date: Sun, 21 Jan 2024 23:09:17 +0800 Subject: [PATCH] Add ResourceDefinitionBackendHandler (#29798) * Refactor RDLBackendHandlerFactory * Add ResourceDefinitionBackendHandler * Add ResourceDefinitionBackendHandler * Add ResourceDefinitionBackendHandler --- .../distsql/handler/type/rdl/RDLExecutor.java | 41 ++++++++++++ .../rdl/aware/DatabaseAwareRDLExecutor.java | 26 ++++---- .../distsql/rdl/RDLBackendHandlerFactory.java | 24 ++++--- .../AlterStorageUnitExecutor.java} | 53 +++++++-------- .../RegisterStorageUnitExecutor.java} | 64 +++++++++---------- .../ResourceDefinitionBackendHandler.java | 47 ++++++++++++++ .../UnregisterStorageUnitExecutor.java} | 37 +++++------ ...phere.distsql.handler.type.rdl.RDLExecutor | 20 ++++++ .../rdl/RDLBackendHandlerFactoryTest.java | 59 ----------------- .../AlterStorageUnitExecutorTest.java} | 46 ++++++------- .../RegisterStorageUnitExecutorTest.java} | 45 ++++--------- .../UnregisterStorageUnitExecutorTest.java} | 39 ++++++----- 12 files changed, 255 insertions(+), 246 deletions(-) create mode 100644 infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/RDLExecutor.java rename proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/StorageUnitDefinitionBackendHandler.java => infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/aware/DatabaseAwareRDLExecutor.java (51%) rename proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/{storage/unit/AlterStorageUnitBackendHandler.java => resource/AlterStorageUnitExecutor.java} (75%) rename proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/{storage/unit/RegisterStorageUnitBackendHandler.java => resource/RegisterStorageUnitExecutor.java} (68%) create mode 100644 proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/ResourceDefinitionBackendHandler.java rename proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/{storage/unit/UnregisterStorageUnitBackendHandler.java => resource/UnregisterStorageUnitExecutor.java} (79%) create mode 100644 proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor delete mode 100644 proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactoryTest.java rename proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/{storage/unit/AlterStorageUnitBackendHandlerTest.java => resource/AlterStorageUnitExecutorTest.java} (73%) rename proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/{storage/unit/RegisterStorageUnitBackendHandlerTest.java => resource/RegisterStorageUnitExecutorTest.java} (69%) rename proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/{storage/unit/UnregisterStorageUnitBackendHandlerTest.java => resource/UnregisterStorageUnitExecutorTest.java} (82%) diff --git a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/RDLExecutor.java b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/RDLExecutor.java new file mode 100644 index 0000000000000..8e533d6a09c23 --- /dev/null +++ b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/RDLExecutor.java @@ -0,0 +1,41 @@ +/* + * 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.distsql.handler.type.rdl; + +import org.apache.shardingsphere.distsql.statement.rdl.RDLStatement; +import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPI; + +/** + * RDL executor. + * + * @param type of RQL statement + */ +@SingletonSPI +public interface RDLExecutor extends TypedSPI { + + /** + * Execute update. + * + * @param sqlStatement SQL statement + */ + void execute(T sqlStatement); + + @Override + Class getType(); +} diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/StorageUnitDefinitionBackendHandler.java b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/aware/DatabaseAwareRDLExecutor.java similarity index 51% rename from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/StorageUnitDefinitionBackendHandler.java rename to infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/aware/DatabaseAwareRDLExecutor.java index 6dbf4ee8bbb7b..81d010af70a86 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/StorageUnitDefinitionBackendHandler.java +++ b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/type/rdl/aware/DatabaseAwareRDLExecutor.java @@ -15,23 +15,23 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.distsql.handler.type.rdl.aware; -import org.apache.shardingsphere.distsql.statement.rdl.StorageUnitDefinitionStatement; +import org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor; +import org.apache.shardingsphere.distsql.statement.rdl.RDLStatement; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.RDLBackendHandler; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; /** - * Storage unit definition backend handler. - * - * @param type of storage unit definition statement + * Database aware RDL executor. + * + * @param type of SQL statement */ -public abstract class StorageUnitDefinitionBackendHandler extends RDLBackendHandler { - - protected StorageUnitDefinitionBackendHandler(final T sqlStatement, final ConnectionSession connectionSession) { - super(sqlStatement, connectionSession); - } +public interface DatabaseAwareRDLExecutor extends RDLExecutor { - protected abstract void checkSQLStatement(ShardingSphereDatabase database, T sqlStatement); + /** + * Set database. + * + * @param database database + */ + void setDatabase(ShardingSphereDatabase database); } diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactory.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactory.java index 85a1941a444a8..a7b8ff4473af7 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactory.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactory.java @@ -19,20 +19,19 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor; +import org.apache.shardingsphere.distsql.handler.type.rdl.aware.DatabaseAwareRDLExecutor; import org.apache.shardingsphere.distsql.statement.rdl.RDLStatement; import org.apache.shardingsphere.distsql.statement.rdl.RuleDefinitionStatement; import org.apache.shardingsphere.distsql.statement.rdl.StorageUnitDefinitionStatement; -import org.apache.shardingsphere.distsql.statement.rdl.alter.AlterStorageUnitStatement; -import org.apache.shardingsphere.distsql.statement.rdl.create.RegisterStorageUnitStatement; -import org.apache.shardingsphere.distsql.statement.rdl.drop.UnregisterStorageUnitStatement; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler; +import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource.ResourceDefinitionBackendHandler; import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.rule.NewRuleDefinitionBackendHandler; import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.rule.RuleDefinitionBackendHandler; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit.AlterStorageUnitBackendHandler; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit.RegisterStorageUnitBackendHandler; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit.UnregisterStorageUnitBackendHandler; import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; +import org.apache.shardingsphere.proxy.backend.util.DatabaseNameUtils; /** * RDL backend handler factory. @@ -59,13 +58,12 @@ public static ProxyBackendHandler newInstance(final RDLStatement sqlStatement, f return new RuleDefinitionBackendHandler<>((RuleDefinitionStatement) sqlStatement, connectionSession); } - private static ProxyBackendHandler getStorageUnitBackendHandler(final StorageUnitDefinitionStatement sqlStatement, final ConnectionSession connectionSession) { - if (sqlStatement instanceof RegisterStorageUnitStatement) { - return new RegisterStorageUnitBackendHandler((RegisterStorageUnitStatement) sqlStatement, connectionSession); + @SuppressWarnings("rawtypes") + private static ResourceDefinitionBackendHandler getStorageUnitBackendHandler(final StorageUnitDefinitionStatement sqlStatement, final ConnectionSession connectionSession) { + RDLExecutor executor = TypedSPILoader.getService(RDLExecutor.class, sqlStatement.getClass()); + if (executor instanceof DatabaseAwareRDLExecutor) { + ((DatabaseAwareRDLExecutor) executor).setDatabase(ProxyContext.getInstance().getDatabase(DatabaseNameUtils.getDatabaseName(sqlStatement, connectionSession))); } - if (sqlStatement instanceof AlterStorageUnitStatement) { - return new AlterStorageUnitBackendHandler((AlterStorageUnitStatement) sqlStatement, connectionSession); - } - return new UnregisterStorageUnitBackendHandler((UnregisterStorageUnitStatement) sqlStatement, connectionSession); + return new ResourceDefinitionBackendHandler(sqlStatement, executor); } } diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/AlterStorageUnitBackendHandler.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitExecutor.java similarity index 75% rename from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/AlterStorageUnitBackendHandler.java rename to proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitExecutor.java index dcee876594604..43d31e683631c 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/AlterStorageUnitBackendHandler.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitExecutor.java @@ -15,12 +15,14 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.distsql.handler.exception.storageunit.DuplicateStorageUnitException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.InvalidStorageUnitsException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException; +import org.apache.shardingsphere.distsql.handler.type.rdl.aware.DatabaseAwareRDLExecutor; import org.apache.shardingsphere.distsql.handler.validate.DataSourcePoolPropertiesValidateHandler; import org.apache.shardingsphere.distsql.segment.DataSourceSegment; import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment; @@ -30,16 +32,12 @@ import org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties; import org.apache.shardingsphere.infra.database.core.connector.url.JdbcUrl; import org.apache.shardingsphere.infra.database.core.connector.url.StandardJdbcUrlParser; -import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties; import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; import org.apache.shardingsphere.infra.exception.core.external.ShardingSphereExternalException; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; -import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader; -import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; import java.sql.SQLException; import java.util.Collection; @@ -53,22 +51,17 @@ * Alter storage unit backend handler. */ @Slf4j -public final class AlterStorageUnitBackendHandler extends StorageUnitDefinitionBackendHandler { +@Setter +public final class AlterStorageUnitExecutor implements DatabaseAwareRDLExecutor { - private final DatabaseType databaseType; + private final DataSourcePoolPropertiesValidateHandler validateHandler = new DataSourcePoolPropertiesValidateHandler(); - private final DataSourcePoolPropertiesValidateHandler validateHandler; - - public AlterStorageUnitBackendHandler(final AlterStorageUnitStatement sqlStatement, final ConnectionSession connectionSession) { - super(sqlStatement, connectionSession); - databaseType = connectionSession.getProtocolType(); - validateHandler = new DataSourcePoolPropertiesValidateHandler(); - } + private ShardingSphereDatabase database; @Override - public ResponseHeader execute(final ShardingSphereDatabase database, final AlterStorageUnitStatement sqlStatement) { - checkSQLStatement(database, sqlStatement); - Map propsMap = DataSourceSegmentsConverter.convert(databaseType, sqlStatement.getStorageUnits()); + public void execute(final AlterStorageUnitStatement sqlStatement) { + checkSQLStatement(sqlStatement); + Map propsMap = DataSourceSegmentsConverter.convert(database.getProtocolType(), sqlStatement.getStorageUnits()); validateHandler.validate(propsMap); try { ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().alterStorageUnits(database.getName(), propsMap); @@ -76,15 +69,13 @@ public ResponseHeader execute(final ShardingSphereDatabase database, final Alter log.error("Alter storage unit failed", ex); throw new InvalidStorageUnitsException(Collections.singleton(ex.getMessage())); } - return new UpdateResponseHeader(sqlStatement); } - @Override - public void checkSQLStatement(final ShardingSphereDatabase database, final AlterStorageUnitStatement sqlStatement) { + private void checkSQLStatement(final AlterStorageUnitStatement sqlStatement) { Collection toBeAlteredStorageUnitNames = getToBeAlteredStorageUnitNames(sqlStatement); checkDuplicatedStorageUnitNames(toBeAlteredStorageUnitNames); - checkStorageUnitNameExisted(database, toBeAlteredStorageUnitNames); - checkDatabase(database, sqlStatement); + checkStorageUnitNameExisted(toBeAlteredStorageUnitNames); + checkDatabase(sqlStatement); } private Collection getToBeAlteredStorageUnitNames(final AlterStorageUnitStatement sqlStatement) { @@ -100,21 +91,21 @@ private Collection getDuplicatedStorageUnitNames(final Collection storageUnitNames.stream().filter(each::equals).count() > 1).collect(Collectors.toList()); } - private void checkStorageUnitNameExisted(final ShardingSphereDatabase database, final Collection storageUnitNames) { + private void checkStorageUnitNameExisted(final Collection storageUnitNames) { Map storageUnits = database.getResourceMetaData().getStorageUnits(); Collection notExistedStorageUnitNames = storageUnitNames.stream().filter(each -> !storageUnits.containsKey(each)).collect(Collectors.toList()); ShardingSpherePreconditions.checkState(notExistedStorageUnitNames.isEmpty(), () -> new MissingRequiredStorageUnitsException(database.getName(), notExistedStorageUnitNames)); } - private void checkDatabase(final ShardingSphereDatabase database, final AlterStorageUnitStatement sqlStatement) { + private void checkDatabase(final AlterStorageUnitStatement sqlStatement) { Map storageUnits = database.getResourceMetaData().getStorageUnits(); Collection invalidStorageUnitNames = sqlStatement.getStorageUnits().stream().collect(Collectors.toMap(DataSourceSegment::getName, each -> each)).entrySet().stream() - .filter(each -> !isIdenticalDatabase(each.getValue(), storageUnits.get(each.getKey()))).map(Entry::getKey).collect(Collectors.toSet()); + .filter(each -> !isSameDatabase(each.getValue(), storageUnits.get(each.getKey()))).map(Entry::getKey).collect(Collectors.toSet()); ShardingSpherePreconditions.checkState(invalidStorageUnitNames.isEmpty(), - () -> new InvalidStorageUnitsException(Collections.singleton(String.format("Cannot alter the database of %s", invalidStorageUnitNames)))); + () -> new InvalidStorageUnitsException(Collections.singleton(String.format("Can not alter the database of %s", invalidStorageUnitNames)))); } - private boolean isIdenticalDatabase(final DataSourceSegment segment, final StorageUnit storageUnit) { + private boolean isSameDatabase(final DataSourceSegment segment, final StorageUnit storageUnit) { String hostName = null; String port = null; String database = null; @@ -122,8 +113,7 @@ private boolean isIdenticalDatabase(final DataSourceSegment segment, final Stora hostName = ((HostnameAndPortBasedDataSourceSegment) segment).getHostname(); port = ((HostnameAndPortBasedDataSourceSegment) segment).getPort(); database = ((HostnameAndPortBasedDataSourceSegment) segment).getDatabase(); - } - if (segment instanceof URLBasedDataSourceSegment) { + } else if (segment instanceof URLBasedDataSourceSegment) { JdbcUrl segmentJdbcUrl = new StandardJdbcUrlParser().parse(((URLBasedDataSourceSegment) segment).getUrl()); hostName = segmentJdbcUrl.getHostname(); port = String.valueOf(segmentJdbcUrl.getPort()); @@ -133,4 +123,9 @@ private boolean isIdenticalDatabase(final DataSourceSegment segment, final Stora return Objects.equals(hostName, connectionProperties.getHostname()) && Objects.equals(port, String.valueOf(connectionProperties.getPort())) && Objects.equals(database, connectionProperties.getCatalog()); } + + @Override + public Class getType() { + return AlterStorageUnitStatement.class; + } } diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/RegisterStorageUnitBackendHandler.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitExecutor.java similarity index 68% rename from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/RegisterStorageUnitBackendHandler.java rename to proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitExecutor.java index c3ec984d505e5..170780f07c51a 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/RegisterStorageUnitBackendHandler.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitExecutor.java @@ -15,25 +15,23 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.distsql.handler.exception.storageunit.DuplicateStorageUnitException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.InvalidStorageUnitsException; +import org.apache.shardingsphere.distsql.handler.type.rdl.aware.DatabaseAwareRDLExecutor; import org.apache.shardingsphere.distsql.handler.validate.DataSourcePoolPropertiesValidateHandler; import org.apache.shardingsphere.distsql.segment.DataSourceSegment; import org.apache.shardingsphere.distsql.segment.converter.DataSourceSegmentsConverter; import org.apache.shardingsphere.distsql.statement.rdl.create.RegisterStorageUnitStatement; -import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties; -import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedRule; import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; import org.apache.shardingsphere.infra.exception.core.external.ShardingSphereExternalException; +import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; +import org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedRule; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; -import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader; -import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; import java.sql.SQLException; import java.util.ArrayList; @@ -44,33 +42,28 @@ import java.util.stream.Collectors; /** - * Register storage unit backend handler. + * Register storage unit executor. */ +@Setter @Slf4j -public final class RegisterStorageUnitBackendHandler extends StorageUnitDefinitionBackendHandler { - - private final DatabaseType databaseType; +public final class RegisterStorageUnitExecutor implements DatabaseAwareRDLExecutor { - private final DataSourcePoolPropertiesValidateHandler validateHandler; + private final DataSourcePoolPropertiesValidateHandler validateHandler = new DataSourcePoolPropertiesValidateHandler(); - public RegisterStorageUnitBackendHandler(final RegisterStorageUnitStatement sqlStatement, final ConnectionSession connectionSession) { - super(sqlStatement, connectionSession); - databaseType = connectionSession.getProtocolType(); - validateHandler = new DataSourcePoolPropertiesValidateHandler(); - } + private ShardingSphereDatabase database; @Override - public ResponseHeader execute(final ShardingSphereDatabase database, final RegisterStorageUnitStatement sqlStatement) { - checkSQLStatement(database, sqlStatement); - Map propsMap = DataSourceSegmentsConverter.convert(databaseType, sqlStatement.getStorageUnits()); + public void execute(final RegisterStorageUnitStatement sqlStatement) { + checkSQLStatement(sqlStatement); + Map propsMap = DataSourceSegmentsConverter.convert(database.getProtocolType(), sqlStatement.getStorageUnits()); if (sqlStatement.isIfNotExists()) { - Collection currentStorageUnits = getCurrentStorageUnitNames(database); - Collection logicalDataSourceNames = getLogicalDataSourceNames(database); + Collection currentStorageUnits = getCurrentStorageUnitNames(); + Collection logicalDataSourceNames = getLogicalDataSourceNames(); propsMap.keySet().removeIf(currentStorageUnits::contains); propsMap.keySet().removeIf(logicalDataSourceNames::contains); } if (propsMap.isEmpty()) { - return new UpdateResponseHeader(sqlStatement); + return; } validateHandler.validate(propsMap); try { @@ -79,22 +72,20 @@ public ResponseHeader execute(final ShardingSphereDatabase database, final Regis log.error("Register storage unit failed", ex); throw new InvalidStorageUnitsException(Collections.singleton(ex.getMessage())); } - return new UpdateResponseHeader(sqlStatement); } - @Override - public void checkSQLStatement(final ShardingSphereDatabase database, final RegisterStorageUnitStatement sqlStatement) { + private void checkSQLStatement(final RegisterStorageUnitStatement sqlStatement) { Collection dataSourceNames = new ArrayList<>(sqlStatement.getStorageUnits().size()); if (!sqlStatement.isIfNotExists()) { - checkDuplicatedDataSourceNames(database, dataSourceNames, sqlStatement); - checkDuplicatedLogicalDataSourceNames(database, dataSourceNames); + checkDuplicatedDataSourceNames(dataSourceNames, sqlStatement); + checkDuplicatedLogicalDataSourceNames(dataSourceNames); } } - private void checkDuplicatedDataSourceNames(final ShardingSphereDatabase database, final Collection dataSourceNames, final RegisterStorageUnitStatement sqlStatement) { + private void checkDuplicatedDataSourceNames(final Collection dataSourceNames, final RegisterStorageUnitStatement sqlStatement) { Collection duplicatedDataSourceNames = new HashSet<>(sqlStatement.getStorageUnits().size(), 1F); for (DataSourceSegment each : sqlStatement.getStorageUnits()) { - if (dataSourceNames.contains(each.getName()) || getCurrentStorageUnitNames(database).contains(each.getName())) { + if (dataSourceNames.contains(each.getName()) || getCurrentStorageUnitNames().contains(each.getName())) { duplicatedDataSourceNames.add(each.getName()); } dataSourceNames.add(each.getName()); @@ -102,8 +93,8 @@ private void checkDuplicatedDataSourceNames(final ShardingSphereDatabase databas ShardingSpherePreconditions.checkState(duplicatedDataSourceNames.isEmpty(), () -> new DuplicateStorageUnitException(duplicatedDataSourceNames)); } - private void checkDuplicatedLogicalDataSourceNames(final ShardingSphereDatabase database, final Collection requiredDataSourceNames) { - Collection logicalDataSourceNames = getLogicalDataSourceNames(database); + private void checkDuplicatedLogicalDataSourceNames(final Collection requiredDataSourceNames) { + Collection logicalDataSourceNames = getLogicalDataSourceNames(); if (logicalDataSourceNames.isEmpty()) { return; } @@ -112,11 +103,16 @@ private void checkDuplicatedLogicalDataSourceNames(final ShardingSphereDatabase () -> new InvalidStorageUnitsException(Collections.singleton(String.format("%s already existed in rule", duplicatedDataSourceNames)))); } - private Collection getCurrentStorageUnitNames(final ShardingSphereDatabase database) { + private Collection getCurrentStorageUnitNames() { return ProxyContext.getInstance().getContextManager().getStorageUnits(database.getName()).keySet(); } - private Collection getLogicalDataSourceNames(final ShardingSphereDatabase database) { + private Collection getLogicalDataSourceNames() { return database.getRuleMetaData().findRules(DataSourceContainedRule.class).stream().map(each -> each.getDataSourceMapper().keySet()).flatMap(Collection::stream).collect(Collectors.toList()); } + + @Override + public Class getType() { + return RegisterStorageUnitStatement.class; + } } diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/ResourceDefinitionBackendHandler.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/ResourceDefinitionBackendHandler.java new file mode 100644 index 0000000000000..016aa0ee03c46 --- /dev/null +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/ResourceDefinitionBackendHandler.java @@ -0,0 +1,47 @@ +/* + * 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.proxy.backend.handler.distsql.rdl.resource; + +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor; +import org.apache.shardingsphere.distsql.statement.rdl.RDLStatement; +import org.apache.shardingsphere.proxy.backend.handler.distsql.DistSQLBackendHandler; +import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader; +import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; + +import java.sql.SQLException; + +/** + * Resource definition backend handler. + */ +// TODO merge to RDLBackendHandler @zhangliang +@RequiredArgsConstructor +public final class ResourceDefinitionBackendHandler implements DistSQLBackendHandler { + + private final RDLStatement sqlStatement; + + @SuppressWarnings("rawtypes") + private final RDLExecutor executor; + + @SuppressWarnings("unchecked") + @Override + public ResponseHeader execute() throws SQLException { + executor.execute(sqlStatement); + return new UpdateResponseHeader(sqlStatement); + } +} diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/UnregisterStorageUnitBackendHandler.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitExecutor.java similarity index 79% rename from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/UnregisterStorageUnitBackendHandler.java rename to proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitExecutor.java index 8b1b84dc72cc0..e430405c4bf26 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/UnregisterStorageUnitBackendHandler.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitExecutor.java @@ -15,13 +15,15 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.broadcast.rule.BroadcastRule; import org.apache.shardingsphere.distsql.handler.exception.storageunit.InvalidStorageUnitsException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.StorageUnitInUsedException; +import org.apache.shardingsphere.distsql.handler.type.rdl.aware.DatabaseAwareRDLExecutor; import org.apache.shardingsphere.distsql.statement.rdl.drop.UnregisterStorageUnitStatement; import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; import org.apache.shardingsphere.infra.exception.core.external.server.ShardingSphereServerException; @@ -29,9 +31,6 @@ import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; import org.apache.shardingsphere.infra.rule.ShardingSphereRule; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; -import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader; -import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; import org.apache.shardingsphere.single.rule.SingleRule; import java.sql.SQLException; @@ -43,42 +42,39 @@ import java.util.stream.Collectors; /** - * Unregister storage unit backend handler. + * Unregister storage unit executor. */ +@Setter @Slf4j -public final class UnregisterStorageUnitBackendHandler extends StorageUnitDefinitionBackendHandler { +public final class UnregisterStorageUnitExecutor implements DatabaseAwareRDLExecutor { - public UnregisterStorageUnitBackendHandler(final UnregisterStorageUnitStatement sqlStatement, final ConnectionSession connectionSession) { - super(sqlStatement, connectionSession); - } + private ShardingSphereDatabase database; @Override - public ResponseHeader execute(final ShardingSphereDatabase database, final UnregisterStorageUnitStatement sqlStatement) { - checkSQLStatement(database, sqlStatement); + public void execute(final UnregisterStorageUnitStatement sqlStatement) { + checkSQLStatement(sqlStatement); try { ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().unregisterStorageUnits(database.getName(), sqlStatement.getStorageUnitNames()); } catch (final SQLException | ShardingSphereServerException ex) { log.error("Unregister storage unit failed", ex); throw new InvalidStorageUnitsException(Collections.singleton(ex.getMessage())); } - return new UpdateResponseHeader(sqlStatement); } - @Override - public void checkSQLStatement(final ShardingSphereDatabase database, final UnregisterStorageUnitStatement sqlStatement) { + private void checkSQLStatement(final UnregisterStorageUnitStatement sqlStatement) { if (!sqlStatement.isIfExists()) { - checkExisted(database, sqlStatement.getStorageUnitNames()); + checkExisted(sqlStatement.getStorageUnitNames()); } - checkInUsed(database, sqlStatement); + checkInUsed(sqlStatement); } - private void checkExisted(final ShardingSphereDatabase database, final Collection storageUnitNames) { + private void checkExisted(final Collection storageUnitNames) { Map storageUnits = database.getResourceMetaData().getStorageUnits(); Collection notExistedStorageUnits = storageUnitNames.stream().filter(each -> !storageUnits.containsKey(each)).collect(Collectors.toList()); ShardingSpherePreconditions.checkState(notExistedStorageUnits.isEmpty(), () -> new MissingRequiredStorageUnitsException(database.getName(), notExistedStorageUnits)); } - private void checkInUsed(final ShardingSphereDatabase database, final UnregisterStorageUnitStatement sqlStatement) { + private void checkInUsed(final UnregisterStorageUnitStatement sqlStatement) { Map>> inUsedStorageUnits = database.getRuleMetaData().getInUsedStorageUnitNameAndRulesMap(); Collection inUsedStorageUnitNames = inUsedStorageUnits.keySet(); inUsedStorageUnitNames.retainAll(sqlStatement.getStorageUnitNames()); @@ -113,4 +109,9 @@ private void checkInUsedIgnoreTables(final Collection inUsedResourceName ShardingSpherePreconditions.checkState(inUsedRules.isEmpty(), () -> new StorageUnitInUsedException(each, inUsedRules)); } } + + @Override + public Class getType() { + return UnregisterStorageUnitStatement.class; + } } diff --git a/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor b/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor new file mode 100644 index 0000000000000..2a5119193534e --- /dev/null +++ b/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.type.rdl.RDLExecutor @@ -0,0 +1,20 @@ +# +# 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. +# + +org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource.RegisterStorageUnitExecutor +org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource.AlterStorageUnitExecutor +org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource.UnregisterStorageUnitExecutor diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactoryTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactoryTest.java deleted file mode 100644 index b1cd46111e149..0000000000000 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/RDLBackendHandlerFactoryTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.proxy.backend.handler.distsql.rdl; - -import org.apache.shardingsphere.distsql.statement.rdl.RuleDefinitionStatement; -import org.apache.shardingsphere.distsql.statement.rdl.alter.AlterStorageUnitStatement; -import org.apache.shardingsphere.distsql.statement.rdl.create.RegisterStorageUnitStatement; -import org.apache.shardingsphere.distsql.statement.rdl.drop.UnregisterStorageUnitStatement; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.rule.RuleDefinitionBackendHandler; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit.AlterStorageUnitBackendHandler; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit.RegisterStorageUnitBackendHandler; -import org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit.UnregisterStorageUnitBackendHandler; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Mockito.mock; - -class RDLBackendHandlerFactoryTest { - - @Test - void assertNewInstanceWithRegisterStorageUnitStatement() { - assertThat(RDLBackendHandlerFactory.newInstance(mock(RegisterStorageUnitStatement.class), mock(ConnectionSession.class)), instanceOf(RegisterStorageUnitBackendHandler.class)); - } - - @Test - void assertNewInstanceWithAlterStorageUnitStatement() { - assertThat(RDLBackendHandlerFactory.newInstance(mock(AlterStorageUnitStatement.class), mock(ConnectionSession.class)), instanceOf(AlterStorageUnitBackendHandler.class)); - } - - @Test - void assertNewInstanceWithUnregisterStorageUnitStatement() { - assertThat(RDLBackendHandlerFactory.newInstance(mock(UnregisterStorageUnitStatement.class), mock(ConnectionSession.class)), instanceOf(UnregisterStorageUnitBackendHandler.class)); - } - - // TODO - @Disabled("enable this when metadata structure adjustment completed") - @Test - void assertNewInstanceWithRuleDefinitionStatement() { - assertThat(RDLBackendHandlerFactory.newInstance(mock(RuleDefinitionStatement.class), mock(ConnectionSession.class)), instanceOf(RuleDefinitionBackendHandler.class)); - } -} diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/AlterStorageUnitBackendHandlerTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitExecutorTest.java similarity index 73% rename from proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/AlterStorageUnitBackendHandlerTest.java rename to proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitExecutorTest.java index d619aa2d5f207..87f4770761e4a 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/AlterStorageUnitBackendHandlerTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitExecutorTest.java @@ -15,27 +15,22 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource; import org.apache.shardingsphere.distsql.handler.exception.storageunit.DuplicateStorageUnitException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.InvalidStorageUnitsException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException; import org.apache.shardingsphere.distsql.handler.validate.DataSourcePoolPropertiesValidateHandler; -import org.apache.shardingsphere.distsql.segment.DataSourceSegment; import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment; import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment; import org.apache.shardingsphere.distsql.statement.rdl.alter.AlterStorageUnitStatement; import org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties; -import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData; import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; -import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; -import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; import org.apache.shardingsphere.test.mock.AutoMockExtension; import org.apache.shardingsphere.test.mock.StaticMockSettings; import org.junit.jupiter.api.BeforeEach; @@ -45,13 +40,11 @@ import org.mockito.Mock; import org.mockito.internal.configuration.plugins.Plugins; -import java.util.Collection; +import java.util.Arrays; import java.util.Collections; -import java.util.LinkedList; import java.util.Properties; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -59,62 +52,60 @@ @ExtendWith(AutoMockExtension.class) @StaticMockSettings(ProxyContext.class) -class AlterStorageUnitBackendHandlerTest { +class AlterStorageUnitExecutorTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private ShardingSphereDatabase database; - private AlterStorageUnitBackendHandler handler; + private AlterStorageUnitExecutor executor; @BeforeEach void setUp() throws ReflectiveOperationException { - ConnectionSession connectionSession = mock(ConnectionSession.class); - when(connectionSession.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "FIXTURE")); - handler = new AlterStorageUnitBackendHandler(mock(AlterStorageUnitStatement.class), connectionSession); - Plugins.getMemberAccessor().set( - handler.getClass().getDeclaredField("validateHandler"), handler, mock(DataSourcePoolPropertiesValidateHandler.class)); + executor = new AlterStorageUnitExecutor(); + Plugins.getMemberAccessor().set(executor.getClass().getDeclaredField("validateHandler"), executor, mock(DataSourcePoolPropertiesValidateHandler.class)); } @Test void assertExecute() { ContextManager contextManager = mockContextManager(mock(MetaDataContexts.class, RETURNS_DEEP_STUBS)); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - when(ProxyContext.getInstance().getDatabase("foo_db")).thenReturn(database); ResourceMetaData resourceMetaData = mock(ResourceMetaData.class, RETURNS_DEEP_STUBS); StorageUnit storageUnit = mock(StorageUnit.class, RETURNS_DEEP_STUBS); ConnectionProperties connectionProperties = mockConnectionProperties("ds_0"); when(storageUnit.getConnectionProperties()).thenReturn(connectionProperties); when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("ds_0", storageUnit)); when(database.getResourceMetaData()).thenReturn(resourceMetaData); - assertThat(handler.execute(database, createAlterStorageUnitStatement("ds_0")), instanceOf(UpdateResponseHeader.class)); + executor.setDatabase(database); + assertDoesNotThrow(() -> executor.execute(createAlterStorageUnitStatement("ds_0"))); } @Test void assertExecuteWithDuplicateStorageUnitNames() { - assertThrows(DuplicateStorageUnitException.class, () -> handler.execute(database, createAlterStorageUnitStatementWithDuplicateStorageUnitNames())); + executor.setDatabase(database); + assertThrows(DuplicateStorageUnitException.class, () -> executor.execute(createAlterStorageUnitStatementWithDuplicateStorageUnitNames())); } @Test void assertExecuteWithNotExistedStorageUnitNames() { MetaDataContexts metaDataContexts = mock(MetaDataContexts.class, RETURNS_DEEP_STUBS); - when(metaDataContexts.getMetaData().getDatabases()).thenReturn(Collections.singletonMap("foo_db", database)); ContextManager contextManager = mockContextManager(metaDataContexts); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - assertThrows(MissingRequiredStorageUnitsException.class, () -> handler.execute(database, createAlterStorageUnitStatement("not_existed"))); + executor.setDatabase(database); + assertThrows(MissingRequiredStorageUnitsException.class, () -> executor.execute(createAlterStorageUnitStatement("not_existed"))); } @Test void assertExecuteWithAlterDatabase() { ContextManager contextManager = mockContextManager(mock(MetaDataContexts.class, RETURNS_DEEP_STUBS)); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - when(ProxyContext.getInstance().getDatabase("foo_db")).thenReturn(database); ResourceMetaData resourceMetaData = mock(ResourceMetaData.class, RETURNS_DEEP_STUBS); StorageUnit storageUnit = mock(StorageUnit.class, RETURNS_DEEP_STUBS); ConnectionProperties connectionProperties = mockConnectionProperties("ds_1"); when(storageUnit.getConnectionProperties()).thenReturn(connectionProperties); when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("ds_0", storageUnit)); when(database.getResourceMetaData()).thenReturn(resourceMetaData); - assertThrows(InvalidStorageUnitsException.class, () -> handler.execute(database, createAlterStorageUnitStatement("ds_0"))); + executor.setDatabase(database); + assertThrows(InvalidStorageUnitsException.class, () -> executor.execute(createAlterStorageUnitStatement("ds_0"))); } private ContextManager mockContextManager(final MetaDataContexts metaDataContexts) { @@ -128,10 +119,9 @@ private AlterStorageUnitStatement createAlterStorageUnitStatement(final String r } private AlterStorageUnitStatement createAlterStorageUnitStatementWithDuplicateStorageUnitNames() { - Collection result = new LinkedList<>(); - result.add(new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "ds_0", "root", "", new Properties())); - result.add(new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties())); - return new AlterStorageUnitStatement(result); + return new AlterStorageUnitStatement(Arrays.asList( + new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "ds_0", "root", "", new Properties()), + new URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties()))); } private ConnectionProperties mockConnectionProperties(final String catalog) { diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/RegisterStorageUnitBackendHandlerTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitExecutorTest.java similarity index 69% rename from proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/RegisterStorageUnitBackendHandlerTest.java rename to proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitExecutorTest.java index 411f387711485..5556300b35afa 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/RegisterStorageUnitBackendHandlerTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitExecutorTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource; import org.apache.shardingsphere.distsql.handler.exception.storageunit.DuplicateStorageUnitException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.InvalidStorageUnitsException; @@ -24,17 +24,12 @@ import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment; import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment; import org.apache.shardingsphere.distsql.statement.rdl.create.RegisterStorageUnitStatement; -import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedRule; -import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; -import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader; -import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; import org.apache.shardingsphere.test.mock.AutoMockExtension; import org.apache.shardingsphere.test.mock.StaticMockSettings; import org.junit.jupiter.api.BeforeEach; @@ -50,8 +45,7 @@ import java.util.LinkedList; import java.util.Properties; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -60,21 +54,19 @@ @ExtendWith(AutoMockExtension.class) @StaticMockSettings(ProxyContext.class) @MockitoSettings(strictness = Strictness.LENIENT) -class RegisterStorageUnitBackendHandlerTest { +class RegisterStorageUnitExecutorTest { @Mock private ShardingSphereDatabase database; - private RegisterStorageUnitBackendHandler handler; + private RegisterStorageUnitExecutor executor; @BeforeEach void setUp() throws ReflectiveOperationException { - ConnectionSession connectionSession = mock(ConnectionSession.class); - when(connectionSession.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "FIXTURE")); when(database.getName()).thenReturn("foo_db"); when(database.getRuleMetaData()).thenReturn(mock(RuleMetaData.class)); - handler = new RegisterStorageUnitBackendHandler(mock(RegisterStorageUnitStatement.class), connectionSession); - Plugins.getMemberAccessor().set(handler.getClass().getDeclaredField("validateHandler"), handler, mock(DataSourcePoolPropertiesValidateHandler.class)); + executor = new RegisterStorageUnitExecutor(); + Plugins.getMemberAccessor().set(executor.getClass().getDeclaredField("validateHandler"), executor, mock(DataSourcePoolPropertiesValidateHandler.class)); } @Test @@ -82,17 +74,14 @@ void assertExecute() { ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS); when(contextManager.getMetaDataContexts()).thenReturn(mock(MetaDataContexts.class, RETURNS_DEEP_STUBS)); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - when(ProxyContext.getInstance().getDatabase("foo_db")).thenReturn(database); - ResponseHeader responseHeader = handler.execute(database, createRegisterStorageUnitStatement()); - assertThat(responseHeader, instanceOf(UpdateResponseHeader.class)); + executor.setDatabase(database); + assertDoesNotThrow(() -> executor.execute(createRegisterStorageUnitStatement())); } @Test void assertExecuteWithDuplicateStorageUnitNamesInStatement() { - ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS); - when(contextManager.getMetaDataContexts()).thenReturn(mock(MetaDataContexts.class, RETURNS_DEEP_STUBS)); - when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - assertThrows(DuplicateStorageUnitException.class, () -> handler.execute(database, createRegisterStorageUnitStatementWithDuplicateStorageUnitNames())); + executor.setDatabase(database); + assertThrows(DuplicateStorageUnitException.class, () -> executor.execute(createRegisterStorageUnitStatementWithDuplicateStorageUnitNames())); } @Test @@ -100,7 +89,8 @@ void assertExecuteWithDuplicateStorageUnitNamesWithResourceMetaData() { ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS); when(contextManager.getStorageUnits("foo_db").keySet()).thenReturn(Collections.singleton("ds_0")); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - assertThrows(DuplicateStorageUnitException.class, () -> handler.execute(database, createRegisterStorageUnitStatement())); + executor.setDatabase(database); + assertThrows(DuplicateStorageUnitException.class, () -> executor.execute(createRegisterStorageUnitStatement())); } @Test @@ -111,15 +101,8 @@ void assertExecuteWithDuplicateStorageUnitNamesWithDataSourceContainedRule() { when(rule.getDataSourceMapper()).thenReturn(Collections.singletonMap("ds_0", Collections.emptyList())); when(database.getRuleMetaData().findRules(DataSourceContainedRule.class)).thenReturn(Collections.singleton(rule)); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - when(ProxyContext.getInstance().getDatabase("foo_db")).thenReturn(database); - assertThrows(InvalidStorageUnitsException.class, () -> handler.execute(database, createRegisterStorageUnitStatement())); - } - - @Test - void assertCheckStatementWithIfNotExists() { - RegisterStorageUnitStatement registerStorageUnitStatementWithIfNotExists = new RegisterStorageUnitStatement(true, Collections.singleton( - new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", "3306", "db_1", "root", "", new Properties()))); - handler.checkSQLStatement(database, registerStorageUnitStatementWithIfNotExists); + executor.setDatabase(database); + assertThrows(InvalidStorageUnitsException.class, () -> executor.execute(createRegisterStorageUnitStatement())); } private RegisterStorageUnitStatement createRegisterStorageUnitStatement() { diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/UnregisterStorageUnitBackendHandlerTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitExecutorTest.java similarity index 82% rename from proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/UnregisterStorageUnitBackendHandlerTest.java rename to proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitExecutorTest.java index 78fcbdde0f478..bb6796e49fe2a 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/storage/unit/UnregisterStorageUnitBackendHandlerTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitExecutorTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.storage.unit; +package org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource; import org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException; import org.apache.shardingsphere.distsql.handler.exception.storageunit.StorageUnitInUsedException; @@ -32,8 +32,6 @@ import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; -import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader; -import org.apache.shardingsphere.proxy.backend.session.ConnectionSession; import org.apache.shardingsphere.shadow.rule.ShadowRule; import org.apache.shardingsphere.single.rule.SingleRule; import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource; @@ -50,8 +48,6 @@ import java.sql.SQLException; import java.util.Collections; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -61,7 +57,7 @@ @ExtendWith(AutoMockExtension.class) @StaticMockSettings(ProxyContext.class) @MockitoSettings(strictness = Strictness.LENIENT) -class UnregisterStorageUnitBackendHandlerTest { +class UnregisterStorageUnitExecutorTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private ShardingSphereDatabase database; @@ -80,7 +76,7 @@ class UnregisterStorageUnitBackendHandlerTest { @Mock private ModeContextManager modeContextManager; - private UnregisterStorageUnitBackendHandler handler; + private UnregisterStorageUnitExecutor executor; @BeforeEach void setUp() { @@ -95,12 +91,11 @@ void setUp() { contextManager = mockContextManager(); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); when(ProxyContext.getInstance().getDatabase("foo_db")).thenReturn(database); - handler = new UnregisterStorageUnitBackendHandler(mock(UnregisterStorageUnitStatement.class), mock(ConnectionSession.class)); + executor = new UnregisterStorageUnitExecutor(); } private ContextManager mockContextManager() { MetaDataContexts metaDataContexts = mock(MetaDataContexts.class, RETURNS_DEEP_STUBS); - when(metaDataContexts.getMetaData().getDatabases()).thenReturn(Collections.singletonMap("foo_db", database)); ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS); when(result.getMetaDataContexts()).thenReturn(metaDataContexts); when(result.getInstanceContext().getModeContextManager()).thenReturn(modeContextManager); @@ -114,16 +109,17 @@ void assertExecute() throws SQLException { when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("foo_ds", storageUnit)); when(database.getResourceMetaData()).thenReturn(resourceMetaData); when(database.getRuleMetaData().getInUsedStorageUnitNameAndRulesMap()).thenReturn(Collections.emptyMap()); - when(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db")).thenReturn(database); UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false); - assertThat(handler.execute(database, unregisterStorageUnitStatement), instanceOf(UpdateResponseHeader.class)); + executor.setDatabase(database); + executor.execute(unregisterStorageUnitStatement); verify(modeContextManager).unregisterStorageUnits("foo_db", unregisterStorageUnitStatement.getStorageUnitNames()); } @Test void assertStorageUnitNameNotExistedExecute() { when(ProxyContext.getInstance().getDatabase("foo_db").getResourceMetaData().getStorageUnits()).thenReturn(Collections.emptyMap()); - assertThrows(MissingRequiredStorageUnitsException.class, () -> handler.execute(database, new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false))); + executor.setDatabase(database); + assertThrows(MissingRequiredStorageUnitsException.class, () -> executor.execute(new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false))); } @Test @@ -134,9 +130,8 @@ void assertStorageUnitNameInUseExecute() { when(storageUnit.getDataSource()).thenReturn(new MockedDataSource()); when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("foo_ds", storageUnit)); when(database.getResourceMetaData()).thenReturn(resourceMetaData); - when(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db")).thenReturn(database); - assertThrows(StorageUnitInUsedException.class, - () -> handler.execute(database, new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false))); + executor.setDatabase(database); + assertThrows(StorageUnitInUsedException.class, () -> executor.execute(new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false))); } @Test @@ -149,8 +144,8 @@ void assertStorageUnitNameInUseWithoutIgnoreSingleTables() { when(storageUnit.getDataSource()).thenReturn(new MockedDataSource()); when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("foo_ds", storageUnit)); when(database.getResourceMetaData()).thenReturn(resourceMetaData); - when(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db")).thenReturn(database); - assertThrows(StorageUnitInUsedException.class, () -> handler.execute(database, new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false))); + executor.setDatabase(database); + assertThrows(StorageUnitInUsedException.class, () -> executor.execute(new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false, false))); } @Test @@ -165,14 +160,16 @@ void assertStorageUnitNameInUseIgnoreSingleTables() throws SQLException { when(database.getResourceMetaData()).thenReturn(resourceMetaData); when(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db")).thenReturn(database); UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), true, false); - assertThat(handler.execute(database, unregisterStorageUnitStatement), instanceOf(UpdateResponseHeader.class)); + executor.setDatabase(database); + executor.execute(unregisterStorageUnitStatement); verify(modeContextManager).unregisterStorageUnits("foo_db", unregisterStorageUnitStatement.getStorageUnitNames()); } @Test void assertExecuteWithIfExists() throws SQLException { UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(true, Collections.singleton("foo_ds"), true, false); - assertThat(handler.execute(database, unregisterStorageUnitStatement), instanceOf(UpdateResponseHeader.class)); + executor.setDatabase(database); + executor.execute(unregisterStorageUnitStatement); verify(modeContextManager).unregisterStorageUnits("foo_db", unregisterStorageUnitStatement.getStorageUnitNames()); } @@ -180,8 +177,8 @@ void assertExecuteWithIfExists() throws SQLException { void assertStorageUnitNameInUseWithIfExists() { when(database.getRuleMetaData()).thenReturn(new RuleMetaData(Collections.singleton(shadowRule))); when(shadowRule.getDataSourceMapper()).thenReturn(Collections.singletonMap("", Collections.singleton("foo_ds"))); - when(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db")).thenReturn(database); UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(true, Collections.singleton("foo_ds"), true, false); - assertThrows(DistSQLException.class, () -> handler.execute(database, unregisterStorageUnitStatement)); + executor.setDatabase(database); + assertThrows(DistSQLException.class, () -> executor.execute(unregisterStorageUnitStatement)); } }