This is an automated email from the ASF dual-hosted git repository.
chengzhang 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 043963d1415 Add PartialRuleUpdateSupported feature and try in encrypt
rule first (#31162)
043963d1415 is described below
commit 043963d1415bcb98a12ab4309f4d71cb199a18a0
Author: Liang Zhang <[email protected]>
AuthorDate: Wed May 8 00:51:06 2024 +0800
Add PartialRuleUpdateSupported feature and try in encrypt rule first
(#31162)
* Add PartialRuleUpdateSupported feature and try in encrypt rule first
* Add PartialRuleUpdateSupported feature and try in encrypt rule first
---
.../shardingsphere/encrypt/rule/EncryptRule.java | 73 ++++++++++++++++++++--
.../infra/rule/PartialRuleUpdateSupported.java | 44 +++++++++++++
.../context/ConfigurationContextManager.java | 35 ++++++-----
3 files changed, 132 insertions(+), 20 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 e2e5f4f6f97..ea67c80bc60 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
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.encrypt.rule;
+import com.google.common.base.Preconditions;
import lombok.Getter;
import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
import
org.apache.shardingsphere.encrypt.api.config.rule.EncryptColumnRuleConfiguration;
@@ -25,27 +26,31 @@ import
org.apache.shardingsphere.encrypt.exception.metadata.EncryptTableNotFound
import
org.apache.shardingsphere.encrypt.exception.metadata.MismatchedEncryptAlgorithmTypeException;
import
org.apache.shardingsphere.encrypt.rule.attribute.EncryptTableMapperRuleAttribute;
import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
+import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
import
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
+import org.apache.shardingsphere.infra.rule.PartialRuleUpdateSupported;
import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
import org.apache.shardingsphere.infra.rule.scope.DatabaseRule;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import java.util.Collection;
-import java.util.LinkedHashMap;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
* Encrypt rule.
*/
-public final class EncryptRule implements DatabaseRule {
+public final class EncryptRule implements DatabaseRule,
PartialRuleUpdateSupported<EncryptRuleConfiguration> {
private final String databaseName;
- @Getter
- private final EncryptRuleConfiguration configuration;
+ private final AtomicReference<EncryptRuleConfiguration> ruleConfig = new
AtomicReference<>();
private final Map<String, EncryptTable> tables;
@@ -54,8 +59,8 @@ public final class EncryptRule implements DatabaseRule {
public EncryptRule(final String databaseName, final
EncryptRuleConfiguration ruleConfig) {
this.databaseName = databaseName;
- configuration = ruleConfig;
- tables = new LinkedHashMap<>();
+ 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())));
for (EncryptTableRuleConfiguration each : ruleConfig.getTables()) {
@@ -107,4 +112,60 @@ public final class EncryptRule implements DatabaseRule {
ShardingSpherePreconditions.checkState(encryptTable.isPresent(), () ->
new EncryptTableNotFoundException(tableName));
return encryptTable.get();
}
+
+ @Override
+ public EncryptRuleConfiguration getConfiguration() {
+ return ruleConfig.get();
+ }
+
+ @Override
+ public void updateConfiguration(final EncryptRuleConfiguration
toBeUpdatedRuleConfig) {
+ ruleConfig.set(toBeUpdatedRuleConfig);
+ }
+
+ @Override
+ public boolean partialUpdateRule(final EncryptRuleConfiguration
toBeUpdatedRuleConfig) {
+ 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));
+ }
+ 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);
+ return true;
+ }
+ // TODO Process update table
+ // TODO Process update encryptors
+ return false;
+ }
+
+ private EncryptTableRuleConfiguration
getEncryptTableRuleConfiguration(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;
+ }
}
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/PartialRuleUpdateSupported.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/PartialRuleUpdateSupported.java
new file mode 100644
index 00000000000..48b9773f997
--- /dev/null
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/PartialRuleUpdateSupported.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.rule;
+
+import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+
+/**
+ * Partial rule update supported.
+ *
+ * @param <T> rule configuration type
+ */
+public interface PartialRuleUpdateSupported<T extends RuleConfiguration> {
+
+ /**
+ * Update rule configuration.
+ *
+ * @param toBeUpdatedRuleConfig to be updated configuration
+ */
+ void updateConfiguration(T toBeUpdatedRuleConfig);
+
+ /**
+ * Partial update.
+ *
+ * @param toBeUpdatedRuleConfig to be updated configuration
+ * @return update success or not
+ */
+ // TODO remove return value when support alter
+ boolean partialUpdateRule(T toBeUpdatedRuleConfig);
+}
diff --git
a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
index 32adc980d52..f79844c4013 100644
---
a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
+++
b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/context/ConfigurationContextManager.java
@@ -35,6 +35,7 @@ import
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUn
import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
import
org.apache.shardingsphere.infra.metadata.database.schema.manager.GenericSchemaManager;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.rule.PartialRuleUpdateSupported;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import
org.apache.shardingsphere.infra.rule.builder.database.DatabaseRulesBuilder;
import org.apache.shardingsphere.infra.rule.builder.global.GlobalRulesBuilder;
@@ -154,15 +155,18 @@ public final class ConfigurationContextManager {
* @param databaseName database name
* @param ruleConfig rule configurations
*/
+ @SuppressWarnings({"unchecked", "rawtypes"})
public synchronized void alterRuleConfiguration(final String databaseName,
final RuleConfiguration ruleConfig) {
- // TODO add feature for partly refresh
- // 1. Judge if impl partly interface
- // 2. compare diff with current and ruleConfig
- // 3. Do partly refresh
- // 4. return
+ ShardingSphereDatabase database =
metaDataContexts.get().getMetaData().getDatabase(databaseName);
+ Collection<ShardingSphereRule> rules = new
LinkedList<>(database.getRuleMetaData().getRules());
+ Optional<ShardingSphereRule> toBeChangedRule =
rules.stream().filter(each ->
each.getConfiguration().getClass().equals(ruleConfig.getClass())).findFirst();
+ if (toBeChangedRule.isPresent() && toBeChangedRule.get() instanceof
PartialRuleUpdateSupported) {
+ if (((PartialRuleUpdateSupported)
toBeChangedRule.get()).partialUpdateRule(ruleConfig)) {
+ ((PartialRuleUpdateSupported)
toBeChangedRule.get()).updateConfiguration(ruleConfig);
+ return;
+ }
+ }
try {
- ShardingSphereDatabase database =
metaDataContexts.get().getMetaData().getDatabase(databaseName);
- Collection<ShardingSphereRule> rules = new
LinkedList<>(database.getRuleMetaData().getRules());
rules.removeIf(each ->
each.getConfiguration().getClass().isAssignableFrom(ruleConfig.getClass()));
rules.addAll(DatabaseRulesBuilder.build(databaseName,
database.getProtocolType(),
database.getResourceMetaData().getStorageUnits().entrySet().stream()
@@ -180,15 +184,18 @@ public final class ConfigurationContextManager {
* @param databaseName database name
* @param ruleConfig rule configurations
*/
+ @SuppressWarnings({"unchecked", "rawtypes"})
public synchronized void dropRuleConfiguration(final String databaseName,
final RuleConfiguration ruleConfig) {
- // TODO add feature for partly refresh
- // 1. Judge if impl partly interface
- // 2. compare diff with current and ruleConfig
- // 3. Remove to be removed partial config
- // 4. return
+ ShardingSphereDatabase database =
metaDataContexts.get().getMetaData().getDatabase(databaseName);
+ Collection<ShardingSphereRule> rules = new
LinkedList<>(database.getRuleMetaData().getRules());
+ Optional<ShardingSphereRule> toBeChangedRule =
rules.stream().filter(each ->
each.getConfiguration().getClass().equals(ruleConfig.getClass())).findFirst();
+ if (toBeChangedRule.isPresent() && toBeChangedRule.get() instanceof
PartialRuleUpdateSupported) {
+ if (((PartialRuleUpdateSupported)
toBeChangedRule.get()).partialUpdateRule(ruleConfig)) {
+ ((PartialRuleUpdateSupported)
toBeChangedRule.get()).updateConfiguration(ruleConfig);
+ return;
+ }
+ }
try {
- ShardingSphereDatabase database =
metaDataContexts.get().getMetaData().getDatabase(databaseName);
- Collection<ShardingSphereRule> rules = new
LinkedList<>(database.getRuleMetaData().getRules());
rules.removeIf(each ->
each.getConfiguration().getClass().isAssignableFrom(ruleConfig.getClass()));
if (!((DatabaseRuleConfiguration) ruleConfig).isEmpty()) {
rules.addAll(DatabaseRulesBuilder.build(databaseName,
database.getProtocolType(),