This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 08f7b3d0fdd Refactor ContextManager.dropResources() (#20621)
08f7b3d0fdd is described below
commit 08f7b3d0fddbb9ceedb1c01b06245412120577bf
Author: zhaojinchao <[email protected]>
AuthorDate: Sun Aug 28 23:31:53 2022 +0800
Refactor ContextManager.dropResources() (#20621)
---
.../mode/manager/ContextManager.java | 40 ++++++++++++++++++----
.../config/database/DataSourcePersistService.java | 15 --------
.../mode/manager/ContextManagerTest.java | 5 ++-
.../database/DataSourcePersistServiceTest.java | 9 -----
.../rdl/resource/DropResourceBackendHandler.java | 13 ++++++-
.../resource/AlterResourceBackendHandlerTest.java | 2 +-
.../resource/DropResourceBackendHandlerTest.java | 6 ++--
7 files changed, 54 insertions(+), 36 deletions(-)
diff --git
a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 24427917947..b63102521f1 100644
---
a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++
b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -239,14 +239,23 @@ public final class ContextManager implements
AutoCloseable {
*
* @param databaseName database name
* @param toBeDroppedResourceNames to be dropped resource names
+ * @throws SQLException SQL exception
*/
- public synchronized void dropResources(final String databaseName, final
Collection<String> toBeDroppedResourceNames) {
- Map<String, DataSource> dataSourceMap =
metaDataContexts.getMetaData().getDatabase(databaseName).getResource().getDataSources();
+ public synchronized void dropResources(final String databaseName, final
Collection<String> toBeDroppedResourceNames) throws SQLException {
// TODO should check to be dropped resources are unused here.
ContextManager is atomic domain to maintain metadata, not Dist SQL handler
- for (String each : toBeDroppedResourceNames) {
- dataSourceMap.remove(each);
- }
-
metaDataContexts.getPersistService().getDataSourceService().drop(metaDataContexts.getMetaData().getActualDatabaseName(databaseName),
toBeDroppedResourceNames);
+ Map<String, DataSourceProperties> toBeReservedDataSourcePropsMap =
getToBeReservedDataSourcePropsMap(databaseName, toBeDroppedResourceNames);
+ SwitchingResource switchingResource = new
ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabase(databaseName).getResource(),
toBeReservedDataSourcePropsMap);
+ Map<String, ShardingSphereDatabase> reloadDatabases =
createChangedDatabases(databaseName, switchingResource, null);
+
deleteTableMetaData(metaDataContexts.getMetaData().getDatabase(databaseName),
reloadDatabases.get(databaseName.toLowerCase()));
+ metaDataContexts.getMetaData().getDatabases().putAll(reloadDatabases);
+
metaDataContexts.getPersistService().getDataSourceService().persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName),
toBeReservedDataSourcePropsMap);
+ toBeDroppedResourceNames.forEach(each ->
metaDataContexts.getMetaData().getDatabase(databaseName).getResource().getDataSources().remove(each));
+ switchingResource.closeStaleDataSources();
+ }
+
+ private Map<String, DataSourceProperties>
getToBeReservedDataSourcePropsMap(final String databaseName, final
Collection<String> toBeDroppedResourceNames) {
+ Map<String, DataSourceProperties> dataSourcePropsMap =
metaDataContexts.getPersistService().getDataSourceService().load(metaDataContexts.getMetaData().getActualDatabaseName(databaseName));
+ return dataSourcePropsMap.entrySet().stream().filter(entry ->
!toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Entry::getKey,
Entry::getValue));
}
/**
@@ -401,6 +410,25 @@ public final class ContextManager implements AutoCloseable
{
}
}
+ private void deleteTableMetaData(final ShardingSphereDatabase
currentDatabase, final ShardingSphereDatabase reloadDatabase) {
+ Map<String, ShardingSphereSchema> toBeDeletedTables =
getToBeDeletedTables(currentDatabase.getSchemas(), reloadDatabase.getSchemas());
+ toBeDeletedTables.forEach(
+ (key, value) -> value.getTables().keySet().forEach(each ->
metaDataContexts.getPersistService().getDatabaseMetaDataService().deleteTable(currentDatabase.getName(),
key, each)));
+ Map<String, ShardingSphereSchema> toBeDeletedSchemas =
getToBeDeletedSchemas(reloadDatabase);
+ toBeDeletedSchemas.keySet().forEach(each ->
metaDataContexts.getPersistService().getDatabaseMetaDataService().deleteSchema(currentDatabase.getName(),
each));
+ }
+
+ private Map<String, ShardingSphereSchema> getToBeDeletedTables(final
Map<String, ShardingSphereSchema> currentSchemas, final Map<String,
ShardingSphereSchema> reloadedSchemas) {
+ Map<String, ShardingSphereSchema> result = new
LinkedHashMap<>(currentSchemas.size(), 1);
+ currentSchemas.entrySet().stream().filter(entry ->
reloadedSchemas.containsKey(entry.getKey())).collect(Collectors.toMap(Entry::getKey,
Entry::getValue))
+ .forEach((key, value) -> result.put(key, new
ShardingSphereSchema(getToBeDeletedTables(value, reloadedSchemas.get(key)))));
+ return result;
+ }
+
+ private Map<String, ShardingSphereTable> getToBeDeletedTables(final
ShardingSphereSchema currentSchema, final ShardingSphereSchema reloadedSchema) {
+ return currentSchema.getTables().entrySet().stream().filter(entry ->
!reloadedSchema.getTables().containsKey(entry.getKey())).collect(Collectors.toMap(Entry::getKey,
Entry::getValue));
+ }
+
private Map<String, ShardingSphereSchema> getToBeDeletedSchemas(final
ShardingSphereDatabase reloadedDatabase) {
Map<String, ShardingSphereSchema> currentSchemas =
metaDataContexts.getMetaData().getDatabase(reloadedDatabase.getName()).getSchemas();
return currentSchemas.entrySet().stream().filter(entry ->
!reloadedDatabase.containsSchema(entry.getKey())).collect(Collectors.toMap(Entry::getKey,
Entry::getValue));
diff --git
a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistService.java
b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistService.java
index 8cbf40b3434..beb9191c673 100644
---
a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistService.java
+++
b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistService.java
@@ -25,7 +25,6 @@ import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
import
org.apache.shardingsphere.mode.metadata.persist.node.DatabaseMetaDataNode;
import org.apache.shardingsphere.mode.persist.PersistRepository;
-import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -108,20 +107,6 @@ public final class DataSourcePersistService implements
DatabaseBasedPersistServi
persist(databaseName, dataSourceConfigs);
}
- /**
- * Drop data sources.
- *
- * @param databaseName database name
- * @param toBeDroppedDataSourceNames data sources to be dropped
- */
- public void drop(final String databaseName, final Collection<String>
toBeDroppedDataSourceNames) {
- Map<String, DataSourceProperties> dataSourcePropsMap =
load(databaseName);
- for (String each : toBeDroppedDataSourceNames) {
- dataSourcePropsMap.remove(each);
- }
- persist(databaseName, dataSourcePropsMap);
- }
-
private String getDatabaseActiveVersion(final String databaseName) {
return
repository.get(DatabaseMetaDataNode.getActiveVersionPath(databaseName));
}
diff --git
a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
index 6a60f9f9106..a26b016e2d9 100644
---
a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
+++
b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
@@ -204,8 +204,11 @@ public final class ContextManagerTest {
}
@Test
- public void assertDropResources() {
+ public void assertDropResources() throws SQLException {
+
when(metaDataContexts.getMetaData().getActualDatabaseName("foo_db")).thenReturn("foo_db");
when(metaDataContexts.getMetaData().getDatabase("foo_db").getResource().getDataSources()).thenReturn(new
HashMap<>(Collections.singletonMap("foo_ds", new MockedDataSource())));
+
when(metaDataContexts.getPersistService()).thenReturn(mock(MetaDataPersistService.class,
RETURNS_DEEP_STUBS));
+
when(metaDataContexts.getPersistService().getDataSourceService().load("foo_db")).thenReturn(Collections.singletonMap("foo_ds",
mock(DataSourceProperties.class)));
contextManager.dropResources("foo_db",
Collections.singleton("foo_ds"));
assertTrue(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db").getResource().getDataSources().isEmpty());
}
diff --git
a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistServiceTest.java
b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistServiceTest.java
index 0a277bb0d9e..ab8010a6df5 100644
---
a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistServiceTest.java
+++
b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/service/config/database/DataSourcePersistServiceTest.java
@@ -88,15 +88,6 @@ public final class DataSourcePersistServiceTest {
verify(repository).persist("/metadata/foo_db/versions/0/dataSources",
expected);
}
- @Test
- public void assertDrop() {
-
when(repository.get("/metadata/foo_db/active_version")).thenReturn("0");
- String actual =
readDataSourceYaml("yaml/persist/data-source-foo.yaml");
-
when(repository.get("/metadata/foo_db/versions/0/dataSources")).thenReturn(actual);
- new DataSourcePersistService(repository).drop("foo_db",
Collections.singleton("foo_ds"));
- verify(repository).persist("/metadata/foo_db/versions/0/dataSources",
"{}" + System.lineSeparator());
- }
-
private DataSource createDataSource(final String name) {
MockedDataSource result = new MockedDataSource();
result.setUrl("jdbc:mysql://localhost:3306/" + name);
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandler.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandler.java
index 88054781fea..7d9990facf1 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandler.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandler.java
@@ -19,14 +19,17 @@ package
org.apache.shardingsphere.proxy.backend.handler.distsql.rdl.resource;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
+import lombok.extern.slf4j.Slf4j;
import
org.apache.shardingsphere.distsql.parser.statement.rdl.drop.DropResourceStatement;
import org.apache.shardingsphere.infra.datanode.DataNode;
import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
+import
org.apache.shardingsphere.infra.distsql.exception.resource.InvalidResourcesException;
import
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
import
org.apache.shardingsphere.infra.distsql.exception.resource.ResourceInUsedException;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import
org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
import
org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedRule;
+import org.apache.shardingsphere.infra.util.exception.ShardingSphereException;
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;
@@ -35,7 +38,9 @@ import
org.apache.shardingsphere.proxy.backend.handler.DatabaseRequiredBackendHa
import org.apache.shardingsphere.singletable.rule.SingleTableRule;
import javax.sql.DataSource;
+import java.sql.SQLException;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.stream.Collectors;
@@ -43,6 +48,7 @@ import java.util.stream.Collectors;
/**
* Drop resource backend handler.
*/
+@Slf4j
public final class DropResourceBackendHandler extends
DatabaseRequiredBackendHandler<DropResourceStatement> {
public DropResourceBackendHandler(final DropResourceStatement
sqlStatement, final ConnectionSession connectionSession) {
@@ -53,7 +59,12 @@ public final class DropResourceBackendHandler extends
DatabaseRequiredBackendHan
public ResponseHeader execute(final String databaseName, final
DropResourceStatement sqlStatement) throws DistSQLException {
Collection<String> toBeDroppedResourceNames = sqlStatement.getNames();
check(databaseName, toBeDroppedResourceNames,
sqlStatement.isIgnoreSingleTables(), sqlStatement.isIfExists());
-
ProxyContext.getInstance().getContextManager().dropResources(databaseName,
toBeDroppedResourceNames);
+ try {
+
ProxyContext.getInstance().getContextManager().dropResources(databaseName,
toBeDroppedResourceNames);
+ } catch (final SQLException | ShardingSphereException ex) {
+ log.error("Drop resource failed", ex);
+ throw new
InvalidResourcesException(Collections.singleton(ex.getMessage()));
+ }
return new UpdateResponseHeader(sqlStatement);
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
index 96379f27121..209a3e56aad 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterResourceBackendHandlerTest.java
@@ -95,7 +95,7 @@ public final class AlterResourceBackendHandlerTest extends
ProxyContextRestorer
}
@Test
- public void assertExecute() throws Exception {
+ public void assertExecute() throws DistSQLException {
ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
ProxyContext.init(contextManager);
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandlerTest.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandlerTest.java
index 41577942bfa..e70bd9efc15 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandlerTest.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/DropResourceBackendHandlerTest.java
@@ -96,7 +96,7 @@ public final class DropResourceBackendHandlerTest extends
ProxyContextRestorer {
}
@Test
- public void assertExecute() throws DistSQLException {
+ public void assertExecute() throws SQLException {
when(ruleMetaData.getRules()).thenReturn(Collections.emptyList());
when(resource.getDataSources()).thenReturn(Collections.singletonMap("foo_ds",
dataSource));
when(database.getResource()).thenReturn(resource);
@@ -148,7 +148,7 @@ public final class DropResourceBackendHandlerTest extends
ProxyContextRestorer {
}
@Test
- public void assertResourceNameInUseIgnoreSingleTables() throws
DistSQLException {
+ public void assertResourceNameInUseIgnoreSingleTables() throws
SQLException {
when(ruleMetaData.getRules()).thenReturn(Collections.singleton(singleTableRule));
when(singleTableRule.getType()).thenReturn("SingleTableRule");
DataNode dataNode = mock(DataNode.class);
@@ -163,7 +163,7 @@ public final class DropResourceBackendHandlerTest extends
ProxyContextRestorer {
}
@Test
- public void assertExecuteWithIfExists() throws DistSQLException {
+ public void assertExecuteWithIfExists() throws SQLException {
DropResourceStatement dropResourceStatement = new
DropResourceStatement(true, Collections.singleton("foo_ds"), true);
assertThat(dropResourceBackendHandler.execute("test",
dropResourceStatement), instanceOf(UpdateResponseHeader.class));
verify(contextManager).dropResources("test",
dropResourceStatement.getNames());