RaigorJiang commented on a change in pull request #14685:
URL: https://github.com/apache/shardingsphere/pull/14685#discussion_r782278388



##########
File path: 
shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/set/excutor/SetReadwriteSplittingStatusExecutor.java
##########
@@ -18,45 +18,164 @@
 package 
org.apache.shardingsphere.proxy.backend.text.distsql.ral.common.set.excutor;
 
 import lombok.AllArgsConstructor;
+import org.apache.shardingsphere.infra.distsql.constant.ExportableConstants;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
 import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
 import org.apache.shardingsphere.infra.eventbus.ShardingSphereEventBus;
 import org.apache.shardingsphere.infra.exception.SchemaNotExistedException;
 import org.apache.shardingsphere.infra.rule.event.impl.DataSourceDisabledEvent;
+import org.apache.shardingsphere.infra.rule.identifier.type.ExportableRule;
+import 
org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.status.storage.StorageNodeStatus;
+import 
org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.status.storage.node.StorageStatusNode;
+import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import 
org.apache.shardingsphere.proxy.backend.exception.NoDatabaseSelectedException;
 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.proxy.backend.text.distsql.ral.common.set.SetStatementExecutor;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.parser.statement.status.SetReadwriteSplittingStatusStatement;
+import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Set readwrite-splitting status executor.
  */
 @AllArgsConstructor
 public final class SetReadwriteSplittingStatusExecutor implements 
SetStatementExecutor {
     
+    private static final String DISABLE = "DISABLE";
+    
     private final SetReadwriteSplittingStatusStatement sqlStatement;
     
     private final ConnectionSession connectionSession;
     
     @Override
     public ResponseHeader execute() throws DistSQLException {
         String schemaName = sqlStatement.getSchema().isPresent() ? 
sqlStatement.getSchema().get().getIdentifier().getValue() : 
connectionSession.getSchemaName();
+        String resourceName = sqlStatement.getResourceName();
+        checkSchema(schemaName);
+        boolean isDisable = DISABLE.equals(sqlStatement.getStatus());
+        if (isDisable) {
+            checkDisablingIsValid(schemaName, resourceName);
+        } else {
+            checkEnablingIsValid(schemaName, resourceName);
+        }
+        ShardingSphereEventBus.getInstance().post(new 
DataSourceDisabledEvent(schemaName, resourceName, isDisable));
+        return new UpdateResponseHeader(sqlStatement);
+    }
+    
+    private void checkSchema(final String schemaName) {
         if (null == schemaName) {
             throw new NoDatabaseSelectedException();
         }
         if 
(!ProxyContext.getInstance().getAllSchemaNames().contains(schemaName)) {
             throw new SchemaNotExistedException(schemaName);
         }
-        String resourceName = sqlStatement.getResourceName();
-        Collection<String> notExistedResources = 
ProxyContext.getInstance().getMetaData(schemaName).getResource().getNotExistedResources(Collections.singleton(resourceName));
-        DistSQLException.predictionThrow(notExistedResources.isEmpty(), new 
RequiredResourceMissedException(schemaName, 
Collections.singleton(resourceName)));
-        ShardingSphereEventBus.getInstance().post(new 
DataSourceDisabledEvent(schemaName, resourceName, 
"DISABLE".equals(sqlStatement.getStatus())));
-        return new UpdateResponseHeader(sqlStatement);
+    }
+    
+    private void checkEnablingIsValid(final String schemaName, final String 
toBeEnabledResource) throws DistSQLException {
+        checkResourceExists(schemaName, toBeEnabledResource);
+        Collection<String> disabledResources = 
getDisabledResources(schemaName);
+        if (!disabledResources.contains(toBeEnabledResource)) {
+            throw new UnsupportedOperationException(String.format("`%s` is not 
disabled", toBeEnabledResource));
+        }
+    }
+    
+    private void checkDisablingIsValid(final String schemaName, final String 
toBeDisabledResource) throws DistSQLException {
+        checkResourceExists(schemaName, toBeDisabledResource);
+        Collection<String> disabledResources = 
getDisabledResources(schemaName);
+        if (disabledResources.contains(toBeDisabledResource)) {
+            throw new UnsupportedOperationException(String.format("`%s` has 
been disabled", toBeDisabledResource));
+        }
+        Map<String, Map<String, String>> readwriteSplittingRules = 
getExportedReadwriteSplittingRules(schemaName);
+        Map<String, String> primaryResources = new HashMap<>();
+        Map<String, String> replicaResources = new HashMap<>();
+        readwriteSplittingRules.entrySet().stream().filter(entry -> 
!entry.getValue().isEmpty())
+                .peek(entry -> addPrimaryResource(primaryResources, 
entry)).forEach(entry -> addReplicaResource(replicaResources, entry));
+        if (primaryResources.containsKey(toBeDisabledResource)) {
+            throw new UnsupportedOperationException(String.format("`%s` is the 
primary data source in the `%s` rule, cannot be disabled", 
+                    toBeDisabledResource, 
primaryResources.get(toBeDisabledResource)));
+        }
+        if (!replicaResources.containsKey(toBeDisabledResource)) {
+            throw new UnsupportedOperationException(String.format("`%s` is not 
used by any readwrite-splitting rules, cannot be disabled", 
toBeDisabledResource));
+        }
+        Set<String> canBeDisabledResources = 
getCanBeDisabledResources(replicaResources, disabledResources);
+        if (!canBeDisabledResources.contains(toBeDisabledResource)) {
+            throw new UnsupportedOperationException(String.format("`%s` is the 
last resource in `%s`, cannot be disabled", toBeDisabledResource, 
replicaResources.get(toBeDisabledResource)));

Review comment:
       last resource or last read resource?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to