This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang 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 23c77312167 Reuse encryptors when update encrypt tables (#31163)
23c77312167 is described below

commit 23c773121676c6115184ed04135cf7b1f877da00
Author: Liang Zhang <[email protected]>
AuthorDate: Wed May 8 14:44:58 2024 +0800

    Reuse encryptors when update encrypt tables (#31163)
---
 .../shardingsphere/encrypt/rule/EncryptRule.java   | 54 +++++++++++-----------
 1 file changed, 26 insertions(+), 28 deletions(-)

diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
index ea67c80bc60..c538eaec53a 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
@@ -34,7 +34,6 @@ import 
org.apache.shardingsphere.infra.rule.scope.DatabaseRule;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -54,6 +53,8 @@ public final class EncryptRule implements DatabaseRule, 
PartialRuleUpdateSupport
     
     private final Map<String, EncryptTable> tables;
     
+    private final ConcurrentHashMap<String, EncryptAlgorithm> encryptors;
+    
     @Getter
     private final RuleAttributes attributes;
     
@@ -61,16 +62,24 @@ public final class EncryptRule implements DatabaseRule, 
PartialRuleUpdateSupport
         this.databaseName = databaseName;
         this.ruleConfig.set(ruleConfig);
         tables = new ConcurrentHashMap<>();
-        Map<String, EncryptAlgorithm> encryptors = 
ruleConfig.getEncryptors().entrySet().stream()
-                .collect(Collectors.toMap(Entry::getKey, entry -> 
TypedSPILoader.getService(EncryptAlgorithm.class, entry.getValue().getType(), 
entry.getValue().getProps())));
+        encryptors = createEncryptors(ruleConfig);
         for (EncryptTableRuleConfiguration each : ruleConfig.getTables()) {
-            each.getColumns().forEach(columnRuleConfig -> 
checkEncryptorType(columnRuleConfig, encryptors));
+            each.getColumns().forEach(this::checkEncryptorType);
             tables.put(each.getName().toLowerCase(), new EncryptTable(each, 
encryptors));
         }
         attributes = new RuleAttributes(new 
EncryptTableMapperRuleAttribute(ruleConfig.getTables()));
     }
     
-    private void checkEncryptorType(final EncryptColumnRuleConfiguration 
columnRuleConfig, final Map<String, EncryptAlgorithm> encryptors) {
+    private ConcurrentHashMap<String, EncryptAlgorithm> createEncryptors(final 
EncryptRuleConfiguration ruleConfig) {
+        ConcurrentHashMap<String, EncryptAlgorithm> result = new 
ConcurrentHashMap<>(ruleConfig.getEncryptors().size(), 1F);
+        for (Entry<String, AlgorithmConfiguration> entry : 
ruleConfig.getEncryptors().entrySet()) {
+            result.put(entry.getKey(), 
TypedSPILoader.getService(EncryptAlgorithm.class, entry.getValue().getType(), 
entry.getValue().getProps()));
+        }
+        return result;
+    }
+    
+    // TODO How to process changed encryptors and tables if check failed? It 
should check before rule change
+    private void checkEncryptorType(final EncryptColumnRuleConfiguration 
columnRuleConfig) {
         
ShardingSpherePreconditions.checkState(encryptors.containsKey(columnRuleConfig.getCipher().getEncryptorName())
                 && 
encryptors.get(columnRuleConfig.getCipher().getEncryptorName()).getMetaData().isSupportDecrypt(),
                 () -> new 
MismatchedEncryptAlgorithmTypeException(databaseName, "Cipher", 
columnRuleConfig.getCipher().getEncryptorName(), "decrypt"));
@@ -128,20 +137,14 @@ public final class EncryptRule implements DatabaseRule, 
PartialRuleUpdateSupport
         Collection<String> toBeAddedTableNames = 
toBeUpdatedRuleConfig.getTables().stream().map(EncryptTableRuleConfiguration::getName).collect(Collectors.toList());
         toBeAddedTableNames.removeAll(tables.keySet());
         if (!toBeAddedTableNames.isEmpty()) {
-            for (String each : toBeAddedTableNames) {
-                EncryptTableRuleConfiguration tableRuleConfig = 
getEncryptTableRuleConfiguration(each, toBeUpdatedRuleConfig);
-                Map<String, AlgorithmConfiguration> encryptorConfigs = 
getEncryptorConfigurations(tableRuleConfig, 
toBeUpdatedRuleConfig.getEncryptors());
-                Map<String, EncryptAlgorithm> encryptors = 
encryptorConfigs.entrySet().stream()
-                        .collect(Collectors.toMap(Entry::getKey, entry -> 
TypedSPILoader.getService(EncryptAlgorithm.class, entry.getValue().getType(), 
entry.getValue().getProps())));
-                tableRuleConfig.getColumns().forEach(columnRuleConfig -> 
checkEncryptorType(columnRuleConfig, encryptors));
-                tables.put(each.toLowerCase(), new 
EncryptTable(tableRuleConfig, encryptors));
-            }
+            toBeAddedTableNames.forEach(each -> addTableRule(each, 
toBeUpdatedRuleConfig));
             return true;
         }
         Collection<String> toBeRemovedTableNames = new 
HashSet<>(tables.keySet());
         
toBeRemovedTableNames.removeAll(toBeUpdatedRuleConfig.getTables().stream().map(EncryptTableRuleConfiguration::getName).collect(Collectors.toList()));
         if (!toBeRemovedTableNames.isEmpty()) {
             
toBeRemovedTableNames.stream().map(String::toLowerCase).forEach(tables::remove);
+            // TODO check and remove unused encryptors
             return true;
         }
         // TODO Process update table
@@ -149,23 +152,18 @@ public final class EncryptRule implements DatabaseRule, 
PartialRuleUpdateSupport
         return false;
     }
     
-    private EncryptTableRuleConfiguration 
getEncryptTableRuleConfiguration(final String tableName, final 
EncryptRuleConfiguration toBeUpdatedRuleConfig) {
+    private void addTableRule(final String tableName, final 
EncryptRuleConfiguration toBeUpdatedRuleConfig) {
+        EncryptTableRuleConfiguration tableRuleConfig = 
getTableRuleConfiguration(tableName, toBeUpdatedRuleConfig);
+        for (Entry<String, AlgorithmConfiguration> entry : 
toBeUpdatedRuleConfig.getEncryptors().entrySet()) {
+            encryptors.computeIfAbsent(entry.getKey(), key -> 
TypedSPILoader.getService(EncryptAlgorithm.class, entry.getValue().getType(), 
entry.getValue().getProps()));
+        }
+        tableRuleConfig.getColumns().forEach(this::checkEncryptorType);
+        tables.put(tableName.toLowerCase(), new EncryptTable(tableRuleConfig, 
encryptors));
+    }
+    
+    private EncryptTableRuleConfiguration getTableRuleConfiguration(final 
String tableName, final EncryptRuleConfiguration toBeUpdatedRuleConfig) {
         Optional<EncryptTableRuleConfiguration> result = 
toBeUpdatedRuleConfig.getTables().stream().filter(table -> 
table.getName().equals(tableName)).findFirst();
         Preconditions.checkState(result.isPresent());
         return result.get();
     }
-    
-    private Map<String, AlgorithmConfiguration> 
getEncryptorConfigurations(final EncryptTableRuleConfiguration tableRuleConfig, 
final Map<String, AlgorithmConfiguration> encryptors) {
-        Map<String, AlgorithmConfiguration> result = new 
HashMap<>(encryptors.size(), 1F);
-        for (EncryptColumnRuleConfiguration each : 
tableRuleConfig.getColumns()) {
-            result.put(each.getCipher().getEncryptorName(), 
encryptors.get(each.getCipher().getEncryptorName()));
-            if (each.getAssistedQuery().isPresent()) {
-                result.put(each.getAssistedQuery().get().getEncryptorName(), 
encryptors.get(each.getAssistedQuery().get().getEncryptorName()));
-            }
-            if (each.getLikeQuery().isPresent()) {
-                result.put(each.getLikeQuery().get().getEncryptorName(), 
encryptors.get(each.getLikeQuery().get().getEncryptorName()));
-            }
-        }
-        return result;
-    }
 }

Reply via email to