Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.shenyu.common.utils.UUIDUtils;

import java.sql.Timestamp;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -259,9 +260,10 @@ public static RuleDO buildRuleDO(final RuleDTO ruleDTO) {
* @param ruleDO the rule do
* @param pluginName the plugin name
* @param conditionDataList the condition data list
* @param beforeConditionDataList the before condition data list
* @return the rule data
*/
public static RuleData transFrom(final RuleDO ruleDO, final String pluginName, final List<ConditionData> conditionDataList) {
public static RuleData transFrom(final RuleDO ruleDO, final String pluginName, final List<ConditionData> conditionDataList, final List<ConditionData> beforeConditionDataList) {
return RuleData.builder()
.id(ruleDO.getId())
.name(ruleDO.getName())
Expand All @@ -273,9 +275,23 @@ public static RuleData transFrom(final RuleDO ruleDO, final String pluginName, f
.loged(ruleDO.getLoged())
.handle(ruleDO.getHandle())
.conditionDataList(conditionDataList)
.beforeConditionDataList(beforeConditionDataList)
.build();
}

/**
* Trans from rule data.
*
* @param ruleDO the rule do
* @param pluginName the plugin name
* @param conditionDataList the condition data list
*
* @return ruleData
*/
public static RuleData transFrom(final RuleDO ruleDO, final String pluginName, final List<ConditionData> conditionDataList) {
return transFrom(ruleDO, pluginName, conditionDataList, Collections.emptyList());
}

@Override
public boolean equals(final Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,17 @@ public int update(final RuleDTO ruleDTO) {
Assert.notNull(before, "the updated rule is not found");
RuleDO ruleDO = RuleDO.buildRuleDO(ruleDTO);
final int ruleCount = ruleMapper.updateSelective(ruleDO);

// need old data for cleaning
final List<RuleConditionDO> beforeRuleCondition = ruleConditionMapper.selectByQuery(new RuleConditionQuery(ruleDO.getId()));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update beforeRuleCondition ? why?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the gateway uses the prefix tree to handle the cache, I can not clean up the history cache if Conditions change, so I pass the pre-modified Conditions to the past for precision cleaning.


//delete rule condition then add
ruleConditionMapper.deleteByQuery(new RuleConditionQuery(ruleDO.getId()));

// insert new condition
addCondition(ruleDO, ruleDTO.getRuleConditions());
if (ruleCount > 0) {
ruleEventPublisher.onUpdated(ruleDO, before, ruleDTO.getRuleConditions());
ruleEventPublisher.onUpdated(ruleDO, before, ruleDTO.getRuleConditions(), beforeRuleCondition);
}
return ruleCount;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,24 @@ public void onCreated(final RuleDO rule, final List<RuleConditionDTO> condition)
* @param rule rule
* @param before before rule
* @param condition condition
* @param beforeCondition beforeCondition
*/
public void onUpdated(final RuleDO rule, final RuleDO before, final List<RuleConditionDTO> condition) {
public void onUpdated(final RuleDO rule, final RuleDO before, final List<RuleConditionDTO> condition, final List<RuleConditionDO> beforeCondition) {
publish(new RuleUpdatedEvent(rule, before, SessionUtil.visitorName()));
publishEvent(rule, condition);
publishEvent(rule, condition, beforeCondition);
}


/**
* on rule updated.
*
* @param rule rule
* @param before before rule
* @param condition condition
*/
public void onUpdated(final RuleDO rule, final RuleDO before, final List<RuleConditionDTO> condition) {
onUpdated(rule, before, condition, Collections.emptyList());
}

/**
* on rule updated.
*
Expand Down Expand Up @@ -176,12 +188,22 @@ public void onRegister(final RuleDO rule, final List<RuleConditionDTO> condition
public void publish(final AdminDataModelChangedEvent event) {
publisher.publishEvent(event);
}

private void publishEvent(final RuleDO ruleDO, final List<RuleConditionDTO> condition) {
// publish change event.
final RuleData rule = RuleDO.transFrom(ruleDO,
ruleMapper.getPluginNameBySelectorId(ruleDO.getSelectorId()),
map(condition, ConditionTransfer.INSTANCE::mapToRuleDTO));
publisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE, DataEventTypeEnum.UPDATE, Collections.singletonList(rule)));
}

private void publishEvent(final RuleDO ruleDO, final List<RuleConditionDTO> condition, final List<RuleConditionDO> beforeCondition) {
// publish change event.
final RuleData rule = RuleDO.transFrom(ruleDO,
ruleMapper.getPluginNameBySelectorId(ruleDO.getSelectorId()),
map(condition, ConditionTransfer.INSTANCE::mapToRuleDTO),
map(beforeCondition, ConditionTransfer.INSTANCE::mapToRuleDO)
);
publisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE, DataEventTypeEnum.UPDATE, Collections.singletonList(rule)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public class RuleData {

private List<ConditionData> conditionDataList;

private List<ConditionData> beforeConditionDataList;

/**
* no args constructor.
*/
Expand All @@ -75,6 +77,7 @@ private RuleData(final Builder builder) {
this.loged = builder.loged;
this.handle = builder.handle;
this.conditionDataList = builder.conditionDataList;
this.beforeConditionDataList = builder.beforeConditionDataList;
}

/**
Expand Down Expand Up @@ -286,6 +289,24 @@ public RuleData setConditionDataList(final List<ConditionData> conditionDataList
return this;
}

/**
* get beforeConditionDataList.
*
* @return beforeConditionDataList
*/
public List<ConditionData> getBeforeConditionDataList() {
return beforeConditionDataList;
}

/**
* set beforeConditionDataList.
*
* @param beforeConditionDataList beforeConditionDataList
*/
public void setBeforeConditionDataList(final List<ConditionData> beforeConditionDataList) {
this.beforeConditionDataList = beforeConditionDataList;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
Expand All @@ -294,16 +315,23 @@ public boolean equals(final Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
RuleData ruleData = (RuleData) o;
return Objects.equals(id, ruleData.id) && Objects.equals(name, ruleData.name) && Objects.equals(pluginName, ruleData.pluginName)
&& Objects.equals(selectorId, ruleData.selectorId) && Objects.equals(matchMode, ruleData.matchMode)
&& Objects.equals(sort, ruleData.sort) && Objects.equals(enabled, ruleData.enabled) && Objects.equals(loged, ruleData.loged)
&& Objects.equals(handle, ruleData.handle) && Objects.equals(conditionDataList, ruleData.conditionDataList);
final RuleData ruleData = (RuleData) o;
return Objects.equals(id, ruleData.id)
&& Objects.equals(name, ruleData.name)
&& Objects.equals(pluginName, ruleData.pluginName)
&& Objects.equals(selectorId, ruleData.selectorId)
&& Objects.equals(matchMode, ruleData.matchMode)
&& Objects.equals(sort, ruleData.sort)
&& Objects.equals(enabled, ruleData.enabled)
&& Objects.equals(loged, ruleData.loged)
&& Objects.equals(handle, ruleData.handle)
&& Objects.equals(conditionDataList, ruleData.conditionDataList)
&& Objects.equals(beforeConditionDataList, ruleData.beforeConditionDataList);
}

@Override
public int hashCode() {
return Objects.hash(id, name, pluginName, selectorId, matchMode, sort, enabled, loged, handle, conditionDataList);
return Objects.hash(id, name, pluginName, selectorId, matchMode, sort, enabled, loged, handle, conditionDataList, beforeConditionDataList);
}

@Override
Expand Down Expand Up @@ -362,6 +390,9 @@ public static final class Builder {

private List<ConditionData> conditionDataList;

private List<ConditionData> beforeConditionDataList;


/**
* no args constructor.
*/
Expand Down Expand Up @@ -486,5 +517,16 @@ public Builder conditionDataList(final List<ConditionData> conditionDataList) {
this.conditionDataList = conditionDataList;
return this;
}

/**
* build conditionDataList.
*
* @param beforeConditionDataList beforeConditionDataList
* @return this
*/
public Builder beforeConditionDataList(final List<ConditionData> beforeConditionDataList) {
this.beforeConditionDataList = beforeConditionDataList;
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public enum RuleTrieEventEnum {
*/
INSERT,

/**
* Shenyu Trie update event.
*/
UPDATE,

/**
* Shenyu Trie remove event.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ private <T> void updateCacheData(@NonNull final T data) {
BaseDataCache.getInstance().cacheRuleData(ruleData);
Optional.ofNullable(handlerMap.get(ruleData.getPluginName()))
.ifPresent(handler -> handler.handlerRule(ruleData));
eventPublisher.publishEvent(new RuleTrieEvent(RuleTrieEventEnum.INSERT, ruleData));
if (CollectionUtils.isEmpty(ruleData.getBeforeConditionDataList())) {
eventPublisher.publishEvent(new RuleTrieEvent(RuleTrieEventEnum.INSERT, ruleData));
} else {
// if has before condition, use upodate
eventPublisher.publishEvent(new RuleTrieEvent(RuleTrieEventEnum.UPDATE, ruleData));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,33 @@ public class ShenyuTrieRuleListener implements ApplicationListener<RuleTrieEvent
public void onApplicationEvent(final RuleTrieEvent event) {
RuleTrieEventEnum eventEnum = event.getRuleTrieEvent();
RuleData ruleData = (RuleData) event.getSource();
// new condition
List<ConditionData> conditionDataList = ruleData.getConditionDataList();
List<ConditionData> filterConditions = conditionDataList.stream()
.filter(conditionData -> ParamTypeEnum.URI.getName().equals(conditionData.getParamType()))
.collect(Collectors.toList());

if (CollectionUtils.isNotEmpty(filterConditions)) {
List<String> uriPaths = filterConditions.stream().map(ConditionData::getParamValue).collect(Collectors.toList());
final ShenyuTrie shenyuTrie = SpringBeanUtils.getInstance().getBean(ShenyuTrie.class);
switch (eventEnum) {
case INSERT:
uriPaths.forEach(path -> SpringBeanUtils.getInstance().getBean(ShenyuTrie.class).putNode(path, ruleData, null));
uriPaths.forEach(path -> shenyuTrie.putNode(path, ruleData, null));
break;
case UPDATE:
final List<ConditionData> beforeConditionDataList = ruleData.getBeforeConditionDataList();
List<ConditionData> beforeFilterConditions = beforeConditionDataList.stream()
.filter(conditionData -> ParamTypeEnum.URI.getName().equals(conditionData.getParamType()))
.collect(Collectors.toList());
List<String> beforeUriPaths = beforeFilterConditions.stream().map(ConditionData::getParamValue).collect(Collectors.toList());

// old condition remove
beforeUriPaths.forEach(path -> shenyuTrie.remove(path, ruleData.getSelectorId(), ruleData.getId()));
// new condition insert
uriPaths.forEach(path -> shenyuTrie.putNode(path, ruleData, null));
break;
case REMOVE:
uriPaths.forEach(path -> SpringBeanUtils.getInstance().getBean(ShenyuTrie.class).remove(path, ruleData.getSelectorId(), ruleData.getId()));
uriPaths.forEach(path -> shenyuTrie.remove(path, ruleData.getSelectorId(), ruleData.getId()));
break;
default:
throw new IllegalStateException("Unexpected value: " + event.getRuleTrieEvent());
Expand Down