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());

Reply via email to