Skip to content

Commit

Permalink
Refactor DatabaseRuleDefinitionExecutor.checkBeforeUpdate (#29912)
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu authored Jan 30, 2024
1 parent 217df49 commit 86d9951
Show file tree
Hide file tree
Showing 73 changed files with 1,101 additions and 618 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,51 @@
import lombok.Setter;
import org.apache.shardingsphere.broadcast.api.config.BroadcastRuleConfiguration;
import org.apache.shardingsphere.broadcast.distsql.statement.CreateBroadcastTableRuleStatement;
import org.apache.shardingsphere.broadcast.rule.BroadcastRule;
import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
import org.apache.shardingsphere.distsql.handler.exception.storageunit.EmptyStorageUnitException;
import org.apache.shardingsphere.distsql.handler.type.rdl.rule.spi.database.DatabaseRuleCreateExecutor;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Collections;
import java.util.HashSet;

/**
* Create broadcast table rule executor.
*/
@Setter
public final class CreateBroadcastTableRuleExecutor implements DatabaseRuleCreateExecutor<CreateBroadcastTableRuleStatement, BroadcastRuleConfiguration> {
public final class CreateBroadcastTableRuleExecutor implements DatabaseRuleCreateExecutor<CreateBroadcastTableRuleStatement, BroadcastRule, BroadcastRuleConfiguration> {

private ShardingSphereDatabase database;

private BroadcastRule rule;

@Override
public void checkBeforeUpdate(final CreateBroadcastTableRuleStatement sqlStatement, final BroadcastRuleConfiguration currentRuleConfig) {
public void checkBeforeUpdate(final CreateBroadcastTableRuleStatement sqlStatement) {
ShardingSpherePreconditions.checkState(!database.getResourceMetaData().getStorageUnits().isEmpty(), () -> new EmptyStorageUnitException(database.getName()));
if (!sqlStatement.isIfNotExists()) {
checkDuplicate(sqlStatement, currentRuleConfig);
checkDuplicate(sqlStatement);
}
}

private void checkDuplicate(final CreateBroadcastTableRuleStatement sqlStatement) {
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement);
ShardingSpherePreconditions.checkState(duplicatedRuleNames.isEmpty(), () -> new DuplicateRuleException("Broadcast", sqlStatement.getTables()));
}

private Collection<String> getDuplicatedRuleNames(final CreateBroadcastTableRuleStatement sqlStatement) {
Collection<String> result = new HashSet<>(null == rule ? Collections.emptySet() : rule.getTables());
result.retainAll(sqlStatement.getTables());
return result;
}

@Override
public BroadcastRuleConfiguration buildToBeCreatedRuleConfiguration(final CreateBroadcastTableRuleStatement sqlStatement, final BroadcastRuleConfiguration currentRuleConfig) {
Collection<String> tables = sqlStatement.getTables();
if (sqlStatement.isIfNotExists()) {
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement, currentRuleConfig);
tables.removeIf(duplicatedRuleNames::contains);
tables.removeIf(getDuplicatedRuleNames(sqlStatement)::contains);
}
return new BroadcastRuleConfiguration(tables);
}
Expand All @@ -60,23 +74,9 @@ public void updateCurrentRuleConfiguration(final BroadcastRuleConfiguration curr
currentRuleConfig.getTables().addAll(toBeCreatedRuleConfig.getTables());
}

private void checkDuplicate(final CreateBroadcastTableRuleStatement sqlStatement, final BroadcastRuleConfiguration currentRuleConfig) {
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement, currentRuleConfig);
ShardingSpherePreconditions.checkState(duplicatedRuleNames.isEmpty(), () -> new DuplicateRuleException("Broadcast", sqlStatement.getTables()));
}

private Collection<String> getDuplicatedRuleNames(final CreateBroadcastTableRuleStatement sqlStatement, final BroadcastRuleConfiguration currentRuleConfig) {
Collection<String> result = new LinkedHashSet<>();
if (null != currentRuleConfig && !currentRuleConfig.getTables().isEmpty()) {
result.addAll(currentRuleConfig.getTables());
}
result.retainAll(sqlStatement.getTables());
return result;
}

@Override
public Class<BroadcastRuleConfiguration> getRuleConfigurationClass() {
return BroadcastRuleConfiguration.class;
public Class<BroadcastRule> getRuleClass() {
return BroadcastRule.class;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import lombok.Setter;
import org.apache.shardingsphere.broadcast.api.config.BroadcastRuleConfiguration;
import org.apache.shardingsphere.broadcast.distsql.statement.DropBroadcastTableRuleStatement;
import org.apache.shardingsphere.broadcast.rule.BroadcastRule;
import org.apache.shardingsphere.distsql.handler.exception.rule.MissingRequiredRuleException;
import org.apache.shardingsphere.distsql.handler.required.DistSQLExecutorCurrentRuleRequired;
import org.apache.shardingsphere.distsql.handler.type.rdl.rule.spi.database.DatabaseRuleDropExecutor;
Expand All @@ -35,19 +36,21 @@
*/
@DistSQLExecutorCurrentRuleRequired("Broadcast")
@Setter
public final class DropBroadcastTableRuleExecutor implements DatabaseRuleDropExecutor<DropBroadcastTableRuleStatement, BroadcastRuleConfiguration> {
public final class DropBroadcastTableRuleExecutor implements DatabaseRuleDropExecutor<DropBroadcastTableRuleStatement, BroadcastRule, BroadcastRuleConfiguration> {

private ShardingSphereDatabase database;

private BroadcastRule rule;

@Override
public void checkBeforeUpdate(final DropBroadcastTableRuleStatement sqlStatement, final BroadcastRuleConfiguration currentRuleConfig) {
public void checkBeforeUpdate(final DropBroadcastTableRuleStatement sqlStatement) {
if (!sqlStatement.isIfExists()) {
checkBroadcastTableRuleExist(sqlStatement, currentRuleConfig);
checkBroadcastTableRuleExist(sqlStatement);
}
}

private void checkBroadcastTableRuleExist(final DropBroadcastTableRuleStatement sqlStatement, final BroadcastRuleConfiguration currentRuleConfig) {
Collection<String> currentRules = currentRuleConfig.getTables();
private void checkBroadcastTableRuleExist(final DropBroadcastTableRuleStatement sqlStatement) {
Collection<String> currentRules = rule.getConfiguration().getTables();
Collection<String> notExistRules = sqlStatement.getTables().stream().filter(each -> !containsIgnoreCase(currentRules, each)).collect(Collectors.toList());
ShardingSpherePreconditions.checkState(notExistRules.isEmpty(), () -> new MissingRequiredRuleException("Broadcast", database.getName(), notExistRules));
}
Expand Down Expand Up @@ -75,8 +78,8 @@ public boolean updateCurrentRuleConfiguration(final DropBroadcastTableRuleStatem
}

@Override
public Class<BroadcastRuleConfiguration> getRuleConfigurationClass() {
return BroadcastRuleConfiguration.class;
public Class<BroadcastRule> getRuleClass() {
return BroadcastRule.class;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.apache.shardingsphere.broadcast.api.config.BroadcastRuleConfiguration;
import org.apache.shardingsphere.broadcast.distsql.statement.CreateBroadcastTableRuleStatement;
import org.apache.shardingsphere.broadcast.rule.BroadcastRule;
import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
import org.apache.shardingsphere.distsql.handler.exception.storageunit.EmptyStorageUnitException;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
Expand All @@ -43,28 +44,37 @@ class CreateBroadcastTableRuleExecutorTest {
void assertCheckSQLStatementWithEmptyStorageUnit() {
BroadcastRuleConfiguration currentConfig = mock(BroadcastRuleConfiguration.class);
when(currentConfig.getTables()).thenReturn(Collections.singleton("t_address"));
CreateBroadcastTableRuleStatement sqlStatement = new CreateBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
when(database.getResourceMetaData().getStorageUnits()).thenReturn(Collections.emptyMap());
executor.setDatabase(database);
assertThrows(EmptyStorageUnitException.class, () -> executor.checkBeforeUpdate(sqlStatement, currentConfig));
BroadcastRule rule = mock(BroadcastRule.class);
when(rule.getConfiguration()).thenReturn(currentConfig);
executor.setRule(rule);
CreateBroadcastTableRuleStatement sqlStatement = new CreateBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
assertThrows(EmptyStorageUnitException.class, () -> executor.checkBeforeUpdate(sqlStatement));
}

@Test
void assertCheckSQLStatementWithDuplicateBroadcastRule() {
BroadcastRuleConfiguration currentConfig = mock(BroadcastRuleConfiguration.class);
when(currentConfig.getTables()).thenReturn(Collections.singleton("t_address"));
CreateBroadcastTableRuleStatement sqlStatement = new CreateBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
executor.setDatabase(mockShardingSphereDatabase());
assertThrows(DuplicateRuleException.class, () -> executor.checkBeforeUpdate(sqlStatement, currentConfig));
BroadcastRule rule = mock(BroadcastRule.class);
when(rule.getConfiguration()).thenReturn(currentConfig);
executor.setRule(rule);
CreateBroadcastTableRuleStatement sqlStatement = new CreateBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
assertThrows(DuplicateRuleException.class, () -> executor.checkBeforeUpdate(sqlStatement));
}

@Test
void assertBuildToBeCreatedRuleConfiguration() {
BroadcastRuleConfiguration currentConfig = new BroadcastRuleConfiguration(new LinkedList<>());
CreateBroadcastTableRuleStatement sqlStatement = new CreateBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
executor.setDatabase(mockShardingSphereDatabase());
executor.checkBeforeUpdate(sqlStatement, currentConfig);
BroadcastRule rule = mock(BroadcastRule.class);
when(rule.getConfiguration()).thenReturn(currentConfig);
executor.setRule(rule);
CreateBroadcastTableRuleStatement sqlStatement = new CreateBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
executor.checkBeforeUpdate(sqlStatement);
BroadcastRuleConfiguration toBeCreatedRuleConfig = executor.buildToBeCreatedRuleConfiguration(sqlStatement, currentConfig);
executor.updateCurrentRuleConfiguration(currentConfig, toBeCreatedRuleConfig);
assertThat(currentConfig.getTables().size(), is(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.apache.shardingsphere.broadcast.api.config.BroadcastRuleConfiguration;
import org.apache.shardingsphere.broadcast.distsql.statement.DropBroadcastTableRuleStatement;
import org.apache.shardingsphere.broadcast.rule.BroadcastRule;
import org.apache.shardingsphere.distsql.handler.exception.rule.MissingRequiredRuleException;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -47,7 +48,10 @@ void setUp() {
@Test
void assertCheckSQLStatementWithoutToBeDroppedRule() {
DropBroadcastTableRuleStatement sqlStatement = new DropBroadcastTableRuleStatement(false, Collections.singleton("t_address"));
assertThrows(MissingRequiredRuleException.class, () -> executor.checkBeforeUpdate(sqlStatement, new BroadcastRuleConfiguration(Collections.emptyList())));
BroadcastRule rule = mock(BroadcastRule.class);
when(rule.getConfiguration()).thenReturn(new BroadcastRuleConfiguration(Collections.emptyList()));
executor.setRule(rule);
assertThrows(MissingRequiredRuleException.class, () -> executor.checkBeforeUpdate(sqlStatement));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
import org.apache.shardingsphere.encrypt.distsql.handler.converter.EncryptRuleStatementConverter;
import org.apache.shardingsphere.encrypt.distsql.segment.EncryptRuleSegment;
import org.apache.shardingsphere.encrypt.distsql.statement.AlterEncryptRuleStatement;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;

import java.util.Collection;
Expand All @@ -46,19 +47,22 @@
*/
@DistSQLExecutorCurrentRuleRequired("Encrypt")
@Setter
public final class AlterEncryptRuleExecutor implements DatabaseRuleAlterExecutor<AlterEncryptRuleStatement, EncryptRuleConfiguration> {
public final class AlterEncryptRuleExecutor implements DatabaseRuleAlterExecutor<AlterEncryptRuleStatement, EncryptRule, EncryptRuleConfiguration> {

private ShardingSphereDatabase database;

private EncryptRule rule;

@Override
public void checkBeforeUpdate(final AlterEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
checkToBeAlteredRules(sqlStatement, currentRuleConfig);
public void checkBeforeUpdate(final AlterEncryptRuleStatement sqlStatement) {
checkToBeAlteredRules(sqlStatement);
checkColumnNames(sqlStatement);
checkToBeAlteredEncryptors(sqlStatement);
}

private void checkToBeAlteredRules(final AlterEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
Collection<String> currentEncryptTableNames = currentRuleConfig.getTables().stream().map(EncryptTableRuleConfiguration::getName).collect(Collectors.toList());
private void checkToBeAlteredRules(final AlterEncryptRuleStatement sqlStatement) {
Collection<String> currentEncryptTableNames = ((EncryptRuleConfiguration) rule.getConfiguration()).getTables()
.stream().map(EncryptTableRuleConfiguration::getName).collect(Collectors.toList());
Collection<String> notExistEncryptTableNames = getToBeAlteredEncryptTableNames(sqlStatement).stream().filter(each -> !currentEncryptTableNames.contains(each)).collect(Collectors.toList());
if (!notExistEncryptTableNames.isEmpty()) {
throw new MissingRequiredRuleException("Encrypt", database.getName(), notExistEncryptTableNames);
Expand Down Expand Up @@ -134,8 +138,8 @@ private void dropUnusedEncryptor(final EncryptRuleConfiguration currentRuleConfi
}

@Override
public Class<EncryptRuleConfiguration> getRuleConfigurationClass() {
return EncryptRuleConfiguration.class;
public Class<EncryptRule> getRuleClass() {
return EncryptRule.class;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.shardingsphere.encrypt.distsql.segment.EncryptColumnItemSegment;
import org.apache.shardingsphere.encrypt.distsql.segment.EncryptRuleSegment;
import org.apache.shardingsphere.encrypt.distsql.statement.CreateEncryptRuleStatement;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
Expand All @@ -44,30 +45,32 @@
* Create encrypt rule executor.
*/
@Setter
public final class CreateEncryptRuleExecutor implements DatabaseRuleCreateExecutor<CreateEncryptRuleStatement, EncryptRuleConfiguration> {
public final class CreateEncryptRuleExecutor implements DatabaseRuleCreateExecutor<CreateEncryptRuleStatement, EncryptRule, EncryptRuleConfiguration> {

private ShardingSphereDatabase database;

private EncryptRule rule;

@Override
public void checkBeforeUpdate(final CreateEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
public void checkBeforeUpdate(final CreateEncryptRuleStatement sqlStatement) {
if (!sqlStatement.isIfNotExists()) {
checkDuplicateRuleNames(sqlStatement, currentRuleConfig);
checkDuplicateRuleNames(sqlStatement);
}
checkColumnNames(sqlStatement);
checkAlgorithmTypes(sqlStatement);
checkToBeCreatedEncryptors(sqlStatement);
checkDataSources();
}

private void checkDuplicateRuleNames(final CreateEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement, currentRuleConfig);
private void checkDuplicateRuleNames(final CreateEncryptRuleStatement sqlStatement) {
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement);
ShardingSpherePreconditions.checkState(duplicatedRuleNames.isEmpty(), () -> new DuplicateRuleException("encrypt", database.getName(), duplicatedRuleNames));
}

private Collection<String> getDuplicatedRuleNames(final CreateEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
private Collection<String> getDuplicatedRuleNames(final CreateEncryptRuleStatement sqlStatement) {
Collection<String> currentRuleNames = new LinkedHashSet<>();
if (null != currentRuleConfig) {
currentRuleNames = currentRuleConfig.getTables().stream().map(EncryptTableRuleConfiguration::getName).collect(Collectors.toSet());
if (null != rule) {
currentRuleNames = ((EncryptRuleConfiguration) rule.getConfiguration()).getTables().stream().map(EncryptTableRuleConfiguration::getName).collect(Collectors.toSet());
}
return sqlStatement.getRules().stream().map(EncryptRuleSegment::getTableName).filter(currentRuleNames::contains).collect(Collectors.toSet());
}
Expand Down Expand Up @@ -139,7 +142,7 @@ private void checkDataSources() {
public EncryptRuleConfiguration buildToBeCreatedRuleConfiguration(final CreateEncryptRuleStatement sqlStatement, final EncryptRuleConfiguration currentRuleConfig) {
Collection<EncryptRuleSegment> segments = sqlStatement.getRules();
if (sqlStatement.isIfNotExists()) {
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement, currentRuleConfig);
Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(sqlStatement);
segments.removeIf(each -> duplicatedRuleNames.contains(each.getTableName()));
}
return EncryptRuleStatementConverter.convert(segments);
Expand All @@ -152,8 +155,8 @@ public void updateCurrentRuleConfiguration(final EncryptRuleConfiguration curren
}

@Override
public Class<EncryptRuleConfiguration> getRuleConfigurationClass() {
return EncryptRuleConfiguration.class;
public Class<EncryptRule> getRuleClass() {
return EncryptRule.class;
}

@Override
Expand Down
Loading

0 comments on commit 86d9951

Please sign in to comment.