1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.encrypt.distsql.handler.update;
19
20 import lombok.Setter;
21 import org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleAlterExecutor;
22 import org.apache.shardingsphere.distsql.handler.required.DistSQLExecutorCurrentRuleRequired;
23 import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
24 import org.apache.shardingsphere.encrypt.config.EncryptRuleConfiguration;
25 import org.apache.shardingsphere.encrypt.distsql.handler.converter.EncryptRuleStatementConverter;
26 import org.apache.shardingsphere.encrypt.distsql.segment.EncryptRuleSegment;
27 import org.apache.shardingsphere.encrypt.distsql.statement.AlterEncryptRuleStatement;
28 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
29 import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
30 import org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
31 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
32 import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.InvalidRuleConfigurationException;
33 import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
34 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
35 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
36
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.LinkedHashSet;
41 import java.util.Map;
42 import java.util.Objects;
43 import java.util.stream.Collectors;
44
45
46
47
48 @DistSQLExecutorCurrentRuleRequired(EncryptRule.class)
49 @Setter
50 public final class AlterEncryptRuleExecutor implements DatabaseRuleAlterExecutor<AlterEncryptRuleStatement, EncryptRule, EncryptRuleConfiguration> {
51
52 private ShardingSphereDatabase database;
53
54 private EncryptRule rule;
55
56 @Override
57 public void checkBeforeUpdate(final AlterEncryptRuleStatement sqlStatement) {
58 checkToBeAlteredRules(sqlStatement);
59 checkColumnNames(sqlStatement);
60 checkToBeAlteredEncryptors(sqlStatement);
61 }
62
63 private void checkToBeAlteredRules(final AlterEncryptRuleStatement sqlStatement) {
64 Collection<String> notExistEncryptTableNames = getToBeAlteredEncryptTableNames(sqlStatement).stream().filter(each -> !rule.getAllTableNames().contains(each)).collect(Collectors.toList());
65 ShardingSpherePreconditions.checkMustEmpty(notExistEncryptTableNames, () -> new MissingRequiredRuleException("Encrypt", database.getName(), notExistEncryptTableNames));
66 }
67
68 private Collection<String> getToBeAlteredEncryptTableNames(final AlterEncryptRuleStatement sqlStatement) {
69 return sqlStatement.getRules().stream().map(EncryptRuleSegment::getTableName).collect(Collectors.toList());
70 }
71
72 private void checkColumnNames(final AlterEncryptRuleStatement sqlStatement) {
73 for (EncryptRuleSegment each : sqlStatement.getRules()) {
74 ShardingSpherePreconditions.checkState(isColumnNameNotConflicts(each),
75 () -> new InvalidRuleConfigurationException("encrypt", "assisted query column or like query column conflicts with logic column"));
76 }
77 }
78
79 private boolean isColumnNameNotConflicts(final EncryptRuleSegment rule) {
80 return rule.getColumns().stream().noneMatch(each -> null != each.getLikeQuery() && each.getName().equals(each.getLikeQuery().getName())
81 || null != each.getAssistedQuery() && each.getName().equals(each.getAssistedQuery().getName()));
82 }
83
84 private void checkToBeAlteredEncryptors(final AlterEncryptRuleStatement sqlStatement) {
85 Collection<AlgorithmSegment> encryptors = new LinkedHashSet<>();
86 sqlStatement.getRules().forEach(each -> each.getColumns().forEach(column -> {
87 encryptors.add(column.getCipher().getEncryptor());
88 if (null != column.getAssistedQuery()) {
89 encryptors.add(column.getAssistedQuery().getEncryptor());
90 }
91 if (null != column.getLikeQuery()) {
92 encryptors.add(column.getLikeQuery().getEncryptor());
93 }
94 }));
95 encryptors.stream().filter(Objects::nonNull).forEach(each -> TypedSPILoader.checkService(EncryptAlgorithm.class, each.getName(), each.getProps()));
96 }
97
98 @Override
99 public EncryptRuleConfiguration buildToBeAlteredRuleConfiguration(final AlterEncryptRuleStatement sqlStatement) {
100 return EncryptRuleStatementConverter.convert(sqlStatement.getRules());
101 }
102
103 @Override
104 public EncryptRuleConfiguration buildToBeDroppedRuleConfiguration(final EncryptRuleConfiguration toBeAlteredRuleConfig) {
105 Collection<String> unusedEncryptor = UnusedAlgorithmFinder.findUnusedEncryptor(rule.getConfiguration());
106 Map<String, AlgorithmConfiguration> toBeDroppedEncryptors = new HashMap<>(unusedEncryptor.size(), 1F);
107 unusedEncryptor.forEach(each -> toBeDroppedEncryptors.put(each, rule.getConfiguration().getEncryptors().get(each)));
108 return new EncryptRuleConfiguration(Collections.emptyList(), toBeDroppedEncryptors);
109 }
110
111 @Override
112 public Class<EncryptRule> getRuleClass() {
113 return EncryptRule.class;
114 }
115
116 @Override
117 public Class<AlterEncryptRuleStatement> getType() {
118 return AlterEncryptRuleStatement.class;
119 }
120 }