This is an automated email from the ASF dual-hosted git repository. jianglongtao pushed a commit to branch fix-33341 in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
commit 34032bcdc0b915205c035ae2bbd01918e4f408b8 Author: RaigorJiang <[email protected]> AuthorDate: Tue Aug 13 15:47:50 2024 +0800 Pick #32420 #32446, Rollback if import database configuration failed --- .../YamlDatabaseConfigurationImportExecutor.java | 11 +++++--- .../ral/updatable/ImportMetaDataExecutorTest.java | 31 ++++++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java index 841f1eaa5ec..76c81c0b754 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java @@ -31,6 +31,7 @@ import org.apache.shardingsphere.infra.exception.core.ShardingSpherePrecondition import org.apache.shardingsphere.infra.exception.core.external.sql.ShardingSphereSQLException; import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.DatabaseCreateExistsException; import org.apache.shardingsphere.infra.exception.kernel.metadata.MissingRequiredDatabaseException; +import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.EmptyStorageUnitException; import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.StorageUnitsOperateException; import org.apache.shardingsphere.infra.instance.InstanceContext; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; @@ -78,12 +79,10 @@ public final class YamlDatabaseConfigurationImportExecutor { public void importDatabaseConfiguration(final YamlProxyDatabaseConfiguration yamlConfig) { String databaseName = yamlConfig.getDatabaseName(); checkDatabase(databaseName); + checkDataSources(databaseName, yamlConfig.getDataSources()); addDatabase(databaseName); - if (null == yamlConfig.getDataSources() || yamlConfig.getDataSources().isEmpty()) { - return; - } - importDataSources(databaseName, yamlConfig.getDataSources()); try { + importDataSources(databaseName, yamlConfig.getDataSources()); importRules(databaseName, yamlConfig.getRules()); } catch (final ShardingSphereSQLException ex) { dropDatabase(databaseName); @@ -91,6 +90,10 @@ public final class YamlDatabaseConfigurationImportExecutor { } } + private void checkDataSources(final String databaseName, final Map<String, YamlProxyDataSourceConfiguration> dataSources) { + ShardingSpherePreconditions.checkState(!dataSources.isEmpty(), () -> new EmptyStorageUnitException(databaseName)); + } + private void checkDatabase(final String databaseName) { ShardingSpherePreconditions.checkState(!Strings.isNullOrEmpty(databaseName), MissingRequiredDatabaseException::new); ShardingSpherePreconditions.checkState(!ProxyContext.getInstance().databaseExists(databaseName), () -> new DatabaseCreateExistsException(databaseName)); diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataExecutorTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataExecutorTest.java index 2d1218cd81e..d87adca15e9 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataExecutorTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportMetaDataExecutorTest.java @@ -17,12 +17,16 @@ package org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable; +import lombok.SneakyThrows; +import org.apache.groovy.util.Maps; +import org.apache.shardingsphere.distsql.handler.validate.DistSQLDataSourcePoolPropertiesValidator; import org.apache.shardingsphere.distsql.statement.ral.updatable.ImportMetaDataStatement; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey; import org.apache.shardingsphere.infra.database.core.DefaultDatabase; import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties; import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.DatabaseCreateExistsException; +import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.EmptyStorageUnitException; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNode; import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; @@ -32,6 +36,7 @@ import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable; import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; +import org.apache.shardingsphere.proxy.backend.util.YamlDatabaseConfigurationImportExecutor; import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource; import org.apache.shardingsphere.test.mock.AutoMockExtension; import org.apache.shardingsphere.test.mock.StaticMockSettings; @@ -40,6 +45,7 @@ import org.apache.shardingsphere.test.util.PropertiesBuilder.Property; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; @@ -62,9 +68,13 @@ import static org.mockito.Mockito.when; @MockitoSettings(strictness = Strictness.LENIENT) class ImportMetaDataExecutorTest { - private static final String METADATA_VALUE = "eyJtZXRhX2RhdGEiOnsiZGF0YWJhc2VzIjp7InNoYXJkaW5nX2RiIjoiZGF0YWJhc2VOYW1lOiBzaGFyZGluZ19kYlxuZGF0YVNvdXJjZXM6XG5ydWxlczpcbiJ9LCJwcm9w" - + "cyI6InByb3BzOlxuICBzeXN0ZW0tbG9nLWxldmVsOiBJTkZPXG4gIHNxbC1zaG93OiBmYWxzZVxuIiwicnVsZXMiOiJydWxlczpcbi0gIUFVVEhPUklUWVxuICBwcml2aWxlZ2U6XG4gICAgdHlwZTogQUxMX1BFUk1JVFRFR" - + "FxuICB1c2VyczpcbiAgLSBhdXRoZW50aWNhdGlvbk1ldGhvZE5hbWU6ICcnXG4gICAgcGFzc3dvcmQ6IHJvb3RcbiAgICB1c2VyOiByb290QCVcbiJ9fQ=="; + private static final String METADATA_VALUE = "eyJtZXRhX2RhdGEiOnsiZGF0YWJhc2VzIjp7InNoYXJkaW5nX2RiIjoiZGF0YWJhc2VOYW1lOiBzaGFyZGluZ19kYlxuZGF0YVNvdXJjZXM6XG4gIGRzXzA6XG4gICAgcGFzc3dvcmQ6IFxu" + + "ICAgIGRhdGFTb3VyY2VDbGFzc05hbWU6IG51bGxcbiAgICB1cmw6IGpkYmM6bXlzcWw6Ly8xMjcuMC4wLjE6MzMwNi9kZW1vX2RzXzA/dXNlU1NMPWZhbHNlXG4gICAgdXNlcm5hbWU6IHJvb3RcbiAgICBtaW5Qb29sU2l6ZTogMVxuICAgI" + + "GNvbm5lY3Rpb25UaW1lb3V0TWlsbGlzZWNvbmRzOiAzMDAwMFxuICAgIG1heExpZmV0aW1lTWlsbGlzZWNvbmRzOiAxODAwMDAwXG4gICAgaWRsZVRpbWVvdXRNaWxsaXNlY29uZHM6IDYwMDAwXG4gICAgbWF4UG9vbFNpemU6IDUwXG4gIG" + + "RzXzE6XG4gICAgcGFzc3dvcmQ6IFxuICAgIGRhdGFTb3VyY2VDbGFzc05hbWU6IG51bGxcbiAgICB1cmw6IGpkYmM6bXlzcWw6Ly8xMjcuMC4wLjE6MzMwNi9kZW1vX2RzXzE/dXNlU1NMPWZhbHNlXG4gICAgdXNlcm5hbWU6IHJvb3RcbiA" + + "gICBtaW5Qb29sU2l6ZTogMVxuICAgIGNvbm5lY3Rpb25UaW1lb3V0TWlsbGlzZWNvbmRzOiAzMDAwMFxuICAgIG1heExpZmV0aW1lTWlsbGlzZWNvbmRzOiAxODAwMDAwXG4gICAgaWRsZVRpbWVvdXRNaWxsaXNlY29uZHM6IDYwMDAwXG4g" + + "ICAgbWF4UG9vbFNpemU6IDUwXG5ydWxlczpcbiJ9LCJwcm9wcyI6InByb3BzOlxuICBzeXN0ZW0tbG9nLWxldmVsOiBJTkZPXG4gIHNxbC1zaG93OiBmYWxzZVxuIiwicnVsZXMiOiJydWxlczpcbi0gIUFVVEhPUklUWVxuICBwcml2aWxlZ" + + "2U6XG4gICAgdHlwZTogQUxMX1BFUk1JVFRFRFxuICB1c2VyczpcbiAgLSBhdXRoZW50aWNhdGlvbk1ldGhvZE5hbWU6ICcnXG4gICAgcGFzc3dvcmQ6IHJvb3RcbiAgICB1c2VyOiByb290QCVcbiJ9fQ=="; private static final String EMPTY = "empty_metadata"; @@ -78,11 +88,11 @@ class ImportMetaDataExecutorTest { } @Test - void assertImportEmptyMetaData() throws SQLException { + void assertImportEmptyMetaData() { init(null); ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS); - executor.executeUpdate(new ImportMetaDataStatement(null, Objects.requireNonNull(ImportMetaDataExecutorTest.class.getResource(featureMap.get(EMPTY))).getPath()), contextManager); - assertNotNull(contextManager.getDatabase("empty_metadata")); + assertThrows(EmptyStorageUnitException.class, () -> executor.executeUpdate( + new ImportMetaDataStatement(null, Objects.requireNonNull(ImportMetaDataExecutorTest.class.getResource(featureMap.get(EMPTY))).getPath()), contextManager)); } @Test @@ -101,11 +111,16 @@ class ImportMetaDataExecutorTest { new ImportMetaDataStatement(null, Objects.requireNonNull(ImportMetaDataExecutorTest.class.getResource(featureMap.get(EMPTY))).getPath()), contextManager)); } + @SneakyThrows({IllegalAccessException.class, NoSuchFieldException.class}) private void init(final String feature) { executor = new ImportMetaDataExecutor(); ContextManager contextManager = mockContextManager(feature); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); when(ProxyContext.getInstance().databaseExists(feature)).thenReturn(true); + YamlDatabaseConfigurationImportExecutor databaseConfigImportExecutor = new YamlDatabaseConfigurationImportExecutor(); + Plugins.getMemberAccessor().set(executor.getClass().getDeclaredField("databaseConfigImportExecutor"), executor, databaseConfigImportExecutor); + Plugins.getMemberAccessor().set(databaseConfigImportExecutor.getClass().getDeclaredField("validateHandler"), databaseConfigImportExecutor, + mock(DistSQLDataSourcePoolPropertiesValidator.class)); } private ContextManager mockContextManager(final String feature) { @@ -126,10 +141,10 @@ class ImportMetaDataExecutorTest { private Map<String, StorageUnit> createStorageUnits() { Map<String, StorageUnit> result = new LinkedHashMap<>(2, 1F); DataSourcePoolProperties dataSourcePoolProps0 = mock(DataSourcePoolProperties.class, RETURNS_DEEP_STUBS); - when(dataSourcePoolProps0.getConnectionPropertySynonyms().getStandardProperties()).thenReturn(Collections.singletonMap("url", "jdbc:mock://127.0.0.1/ds_0")); + when(dataSourcePoolProps0.getConnectionPropertySynonyms().getStandardProperties()).thenReturn(Maps.of("url", "jdbc:mock://127.0.0.1/ds_0", "username", "test")); result.put("ds_0", new StorageUnit(mock(StorageNode.class), dataSourcePoolProps0, new MockedDataSource())); DataSourcePoolProperties dataSourcePoolProps1 = mock(DataSourcePoolProperties.class, RETURNS_DEEP_STUBS); - when(dataSourcePoolProps1.getConnectionPropertySynonyms().getStandardProperties()).thenReturn(Collections.singletonMap("url", "jdbc:mock://127.0.0.1/ds_1")); + when(dataSourcePoolProps1.getConnectionPropertySynonyms().getStandardProperties()).thenReturn(Maps.of("url", "jdbc:mock://127.0.0.1/ds_1", "username", "test")); result.put("ds_1", new StorageUnit(mock(StorageNode.class), dataSourcePoolProps1, new MockedDataSource())); return result; }
