Copilot commented on code in PR #6231:
URL: https://github.com/apache/shenyu/pull/6231#discussion_r2542362246
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java:
##########
@@ -92,71 +96,56 @@ public abstract class AbstractShenyuPlugin implements
ShenyuPlugin {
public Mono<Void> execute(final ServerWebExchange exchange, final
ShenyuPluginChain chain) {
initCacheConfig();
final String pluginName = named();
- PluginData pluginData =
BaseDataCache.getInstance().obtainPluginData(pluginName);
- // early exit
- if (Objects.isNull(pluginData) || !pluginData.getEnabled()) {
- return chain.execute(exchange);
- }
final String path = getRawPath(exchange);
- List<SelectorData> selectors =
BaseDataCache.getInstance().obtainSelectorData(pluginName);
- if (CollectionUtils.isEmpty(selectors)) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ PluginDataDecisionMaker pluginDataDecisionMaker = new
PluginDataDecisionMaker();
+ List<PluginData> pluginDataList =
pluginDataDecisionMaker.getData(pluginName);
+ if (CollectionUtils.isEmpty(pluginDataList) ||
!pluginDataDecisionMaker.shouldContinue(pluginDataList.get(0))) {
+ return pluginDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
- SelectorData selectorData = obtainSelectorDataCacheIfEnabled(path);
- // handle Selector
- if (Objects.nonNull(selectorData) &&
StringUtils.isBlank(selectorData.getId())) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ SelectorDataDecisionMaker selectorDataDecisionMaker = new
SelectorDataDecisionMaker();
+ List<SelectorData> selectorDataList =
selectorDataDecisionMaker.getData(pluginName);
+ if (CollectionUtils.isEmpty(selectorDataList)) {
+ return selectorDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
- if (Objects.isNull(selectorData)) {
- selectorData = trieMatchSelector(exchange, pluginName, path);
- if (Objects.isNull(selectorData)) {
- selectorData = defaultMatchSelector(exchange, selectors, path);
- if (Objects.isNull(selectorData)) {
- return handleSelectorIfNull(pluginName, exchange, chain);
- }
- }
+
+ SelectorData selectorData =
selectorDataDecisionMaker.matchData(exchange, selectorDataList, path);
+ if (selectorData == null) {
+ return selectorDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
+
printLog(selectorData, pluginName);
- if (!selectorData.getContinued()) {
- // if continued, not match rules
+ if (!selectorDataDecisionMaker.shouldContinue(selectorData)) {
Review Comment:
Incorrect usage of `shouldContinue()`. The `shouldContinue` method checks if
data is enabled (`data.getEnabled()`), but the original logic checked
`selectorData.getContinued()` which indicates whether to continue processing
rules. These are two different concepts: `enabled` controls if the selector is
active, while `continued` controls whether to proceed to rule matching. The
correct check should be `if (!selectorData.getContinued())` instead of `if
(!selectorDataDecisionMaker.shouldContinue(selectorData))`.
```suggestion
if (!selectorData.getContinued()) {
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/SelectorDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.SelectorDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class SelectorDataDecisionMaker extends
AbstractMatchDecisionMaker<SelectorData> {
+ public SelectorDataDecisionMaker() {
+ super(new SelectorDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public SelectorData matchData(ServerWebExchange exchange,
List<SelectorData> dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
+ }
+
+ @Override
+ public boolean shouldContinue(SelectorData data) {
+ return data != null && data.getEnabled();
Review Comment:
The `shouldContinue` method logic is incorrect for SelectorData. It checks
`data.getEnabled()`, but based on its usage in AbstractShenyuPlugin line 119,
it should check `data.getContinued()` instead. The `continued` field determines
whether to continue processing rules after a selector matches, which is
different from the `enabled` field that controls if the selector is active.
```suggestion
return data != null && data.getContinued();
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java:
##########
@@ -92,71 +96,56 @@ public abstract class AbstractShenyuPlugin implements
ShenyuPlugin {
public Mono<Void> execute(final ServerWebExchange exchange, final
ShenyuPluginChain chain) {
initCacheConfig();
final String pluginName = named();
- PluginData pluginData =
BaseDataCache.getInstance().obtainPluginData(pluginName);
- // early exit
- if (Objects.isNull(pluginData) || !pluginData.getEnabled()) {
- return chain.execute(exchange);
- }
final String path = getRawPath(exchange);
- List<SelectorData> selectors =
BaseDataCache.getInstance().obtainSelectorData(pluginName);
- if (CollectionUtils.isEmpty(selectors)) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ PluginDataDecisionMaker pluginDataDecisionMaker = new
PluginDataDecisionMaker();
+ List<PluginData> pluginDataList =
pluginDataDecisionMaker.getData(pluginName);
+ if (CollectionUtils.isEmpty(pluginDataList) ||
!pluginDataDecisionMaker.shouldContinue(pluginDataList.get(0))) {
+ return pluginDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
- SelectorData selectorData = obtainSelectorDataCacheIfEnabled(path);
- // handle Selector
- if (Objects.nonNull(selectorData) &&
StringUtils.isBlank(selectorData.getId())) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ SelectorDataDecisionMaker selectorDataDecisionMaker = new
SelectorDataDecisionMaker();
+ List<SelectorData> selectorDataList =
selectorDataDecisionMaker.getData(pluginName);
+ if (CollectionUtils.isEmpty(selectorDataList)) {
+ return selectorDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
- if (Objects.isNull(selectorData)) {
- selectorData = trieMatchSelector(exchange, pluginName, path);
- if (Objects.isNull(selectorData)) {
- selectorData = defaultMatchSelector(exchange, selectors, path);
- if (Objects.isNull(selectorData)) {
- return handleSelectorIfNull(pluginName, exchange, chain);
- }
- }
+
+ SelectorData selectorData =
selectorDataDecisionMaker.matchData(exchange, selectorDataList, path);
+ if (selectorData == null) {
+ return selectorDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
+
printLog(selectorData, pluginName);
- if (!selectorData.getContinued()) {
- // if continued, not match rules
+ if (!selectorDataDecisionMaker.shouldContinue(selectorData)) {
return doExecute(exchange, chain, selectorData,
defaultRuleData(selectorData));
}
- List<RuleData> rules =
BaseDataCache.getInstance().obtainRuleData(selectorData.getId());
- if (CollectionUtils.isEmpty(rules)) {
- return handleRuleIfNull(pluginName, exchange, chain);
+
+
+ RuleDataDecisionMaker ruleDataDecisionMaker = new
RuleDataDecisionMaker();
Review Comment:
Creating a new `RuleDataDecisionMaker` instance on every request is
inefficient. This should be a reusable class field to avoid unnecessary object
allocation.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java:
##########
@@ -92,71 +96,56 @@ public abstract class AbstractShenyuPlugin implements
ShenyuPlugin {
public Mono<Void> execute(final ServerWebExchange exchange, final
ShenyuPluginChain chain) {
initCacheConfig();
final String pluginName = named();
- PluginData pluginData =
BaseDataCache.getInstance().obtainPluginData(pluginName);
- // early exit
- if (Objects.isNull(pluginData) || !pluginData.getEnabled()) {
- return chain.execute(exchange);
- }
final String path = getRawPath(exchange);
- List<SelectorData> selectors =
BaseDataCache.getInstance().obtainSelectorData(pluginName);
- if (CollectionUtils.isEmpty(selectors)) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ PluginDataDecisionMaker pluginDataDecisionMaker = new
PluginDataDecisionMaker();
+ List<PluginData> pluginDataList =
pluginDataDecisionMaker.getData(pluginName);
+ if (CollectionUtils.isEmpty(pluginDataList) ||
!pluginDataDecisionMaker.shouldContinue(pluginDataList.get(0))) {
+ return pluginDataDecisionMaker.handleEmpty(pluginName, exchange,
chain);
}
- SelectorData selectorData = obtainSelectorDataCacheIfEnabled(path);
- // handle Selector
- if (Objects.nonNull(selectorData) &&
StringUtils.isBlank(selectorData.getId())) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ SelectorDataDecisionMaker selectorDataDecisionMaker = new
SelectorDataDecisionMaker();
Review Comment:
Creating a new `SelectorDataDecisionMaker` instance on every request is
inefficient. This should be a reusable class field to avoid unnecessary object
allocation.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/provider/PluginDataProvider.java:
##########
@@ -0,0 +1,15 @@
+package org.apache.shenyu.plugin.base.provider;
+
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.plugin.base.cache.BaseDataCache;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PluginDataProvider implements DataProvider<PluginData> {
+ @Override
+ public List<PluginData> getData(String pluginName) {
+ PluginData data =
BaseDataCache.getInstance().obtainPluginData(pluginName);
+ return data != null ? Collections.singletonList(data) :
Collections.emptyList();
+ }
+}
Review Comment:
Missing class-level and method-level documentation. This new public class
should include Javadoc explaining its purpose and how it fits into the data
provider pattern.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/provider/DataProvider.java:
##########
@@ -0,0 +1,7 @@
+package org.apache.shenyu.plugin.base.provider;
+
+import java.util.List;
+
+public interface DataProvider<T> {
Review Comment:
Missing class-level and method-level documentation. This is a new public
interface that should include Javadoc explaining its purpose, usage, and the
meaning of the type parameter `T` and method parameter `key`.
```suggestion
/**
* A generic interface for providing data based on a given key.
* <p>
* Implementations of this interface are responsible for retrieving a list
of data items
* of type {@code T} associated with the specified key. This can be used in
plugin systems
* or other contexts where data needs to be fetched dynamically.
*
* @param <T> the type of data provided by this provider
*/
public interface DataProvider<T> {
/**
* Retrieves a list of data items associated with the specified key.
*
* @param key the key used to look up the data; its meaning is defined
by the implementation
* @return a list of data items of type {@code T} associated with the
given key,
* or an empty list if no data is found
*/
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/PluginDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.PluginDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class PluginDataDecisionMaker extends
AbstractMatchDecisionMaker<PluginData> {
+ public PluginDataDecisionMaker() {
+ super(new PluginDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ protected PluginData matchData(ServerWebExchange exchange,
List<PluginData> dataList, String path) {
Review Comment:
Inconsistent visibility modifier. This method is declared as `protected`
while the same method in `SelectorDataDecisionMaker` (line 22) and
`RuleDataDecisionMaker` (line 22) uses different visibility modifiers. For
consistency across the class hierarchy, all implementations should use the same
visibility modifier.
```suggestion
public PluginData matchData(ServerWebExchange exchange, List<PluginData>
dataList, String path) {
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/provider/SelectorDataProvider.java:
##########
@@ -0,0 +1,18 @@
+package org.apache.shenyu.plugin.base.provider;
+
+
+
+
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.base.cache.BaseDataCache;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SelectorDataProvider implements DataProvider<SelectorData> {
+ @Override
+ public List<SelectorData> getData(String selectorName) {
+ List<SelectorData> data =
BaseDataCache.getInstance().obtainSelectorData(selectorName);
+ return data != null ? data : Collections.emptyList();
+ }
+}
Review Comment:
Missing class-level and method-level documentation. This new public class
should include Javadoc explaining its purpose and how it fits into the data
provider pattern.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/RuleDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.RuleDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class RuleDataDecisionMaker extends
AbstractMatchDecisionMaker<RuleData> {
+ public RuleDataDecisionMaker() {
+ super(new RuleDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public RuleData matchData(ServerWebExchange exchange, List<RuleData>
dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
Review Comment:
The `matchData` implementation is incomplete and incorrect. It simply
returns the first element from the list without performing any actual matching
logic. The original implementation included trie cache matching
(`trieMatchRule`) and complex condition-based matching (`defaultMatchRule`).
This oversimplification will cause incorrect rule selection and break existing
functionality.
```suggestion
// Try to match using trie cache first
RuleData rule = trieMatchRule(exchange, dataList, path);
if (rule != null) {
return rule;
}
// Fallback to default matching logic
return defaultMatchRule(exchange, dataList, path);
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/SelectorDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.SelectorDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class SelectorDataDecisionMaker extends
AbstractMatchDecisionMaker<SelectorData> {
+ public SelectorDataDecisionMaker() {
+ super(new SelectorDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public SelectorData matchData(ServerWebExchange exchange,
List<SelectorData> dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
+ }
+
+ @Override
+ public boolean shouldContinue(SelectorData data) {
+ return data != null && data.getEnabled();
+ }
Review Comment:
The `matchData` implementation is incomplete and incorrect. It simply
returns the first element from the list without performing any actual matching
logic. The original implementation included trie cache matching
(`trieMatchSelector`) and complex condition-based matching
(`defaultMatchSelector`). This oversimplification will cause incorrect selector
selection and break existing functionality.
```suggestion
// Try trie-based matching first
SelectorData trieMatched = trieMatchSelector(dataList, path);
if (trieMatched != null) {
return trieMatched;
}
// Fallback to default condition-based matching
return defaultMatchSelector(exchange, dataList);
}
@Override
public boolean shouldContinue(SelectorData data) {
return data != null && data.getEnabled();
}
/**
* Trie-based selector matching.
* @param dataList the list of selectors
* @param path the request path
* @return the matched SelectorData or null
*/
private SelectorData trieMatchSelector(List<SelectorData> dataList,
String path) {
for (SelectorData selector : dataList) {
// Example: check if selector has a trie cache and matches the
path
// This is a placeholder; actual implementation may differ
if (selector.getType() != null && selector.getType() == 1) { //
suppose type 1 means trie
if (selector.getMatchMode() != null &&
selector.getMatchMode() == 0) { // suppose matchMode 0 is exact
if (path.equals(selector.getSelectorName())) {
return selector;
}
}
// Add more trie-based logic as needed
}
}
return null;
}
/**
* Default condition-based selector matching.
* @param exchange the web exchange
* @param dataList the list of selectors
* @return the matched SelectorData or null
*/
private SelectorData defaultMatchSelector(ServerWebExchange exchange,
List<SelectorData> dataList) {
for (SelectorData selector : dataList) {
// Example: check if selector is enabled and matches some
condition
if (Boolean.TRUE.equals(selector.getEnabled())) {
// Placeholder for actual condition matching logic
// For example, match by some attribute in exchange or
selector
// Here, we just return the first enabled selector
return selector;
}
}
return null;
}
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/provider/SelectorDataProvider.java:
##########
@@ -0,0 +1,18 @@
+package org.apache.shenyu.plugin.base.provider;
+
+
+
+
Review Comment:
[nitpick] Multiple consecutive blank lines (lines 3-5). Consider removing
the extra blank lines to follow consistent formatting conventions.
```suggestion
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/SelectorDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.SelectorDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class SelectorDataDecisionMaker extends
AbstractMatchDecisionMaker<SelectorData> {
+ public SelectorDataDecisionMaker() {
+ super(new SelectorDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public SelectorData matchData(ServerWebExchange exchange,
List<SelectorData> dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
+ }
+
+ @Override
+ public boolean shouldContinue(SelectorData data) {
+ return data != null && data.getEnabled();
+ }
+}
Review Comment:
Missing class-level and method-level documentation. This new public class
should include Javadoc explaining its purpose in the selector matching process
and document each overridden method.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/RuleDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.RuleDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class RuleDataDecisionMaker extends
AbstractMatchDecisionMaker<RuleData> {
+ public RuleDataDecisionMaker() {
+ super(new RuleDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public RuleData matchData(ServerWebExchange exchange, List<RuleData>
dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
+ }
+
+ @Override
+ protected boolean shouldContinue(RuleData data) {
+ return data != null && data.getEnabled();
+ }
+}
Review Comment:
Missing class-level and method-level documentation. This new public class
should include Javadoc explaining its purpose in the rule matching process and
document each overridden method.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/PluginDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.PluginDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class PluginDataDecisionMaker extends
AbstractMatchDecisionMaker<PluginData> {
+ public PluginDataDecisionMaker() {
+ super(new PluginDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ protected PluginData matchData(ServerWebExchange exchange,
List<PluginData> dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
+ }
+
+ @Override
+ public boolean shouldContinue(PluginData data) {
+ return data != null && data.getEnabled();
+ }
+}
Review Comment:
Missing class-level and method-level documentation. This new public class
should include Javadoc explaining its purpose in the plugin data decision
process and document each overridden method.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/RuleDataDecisionMaker.java:
##########
@@ -0,0 +1,30 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.RuleDataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public class RuleDataDecisionMaker extends
AbstractMatchDecisionMaker<RuleData> {
+ public RuleDataDecisionMaker() {
+ super(new RuleDataProvider());
+ }
+
+ @Override
+ public Mono<Void> handleEmpty(String pluginName, ServerWebExchange
exchange, ShenyuPluginChain chain) {
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public RuleData matchData(ServerWebExchange exchange, List<RuleData>
dataList, String path) {
+ return dataList.isEmpty() ? null : dataList.get(0);
+ }
+
+ @Override
+ protected boolean shouldContinue(RuleData data) {
Review Comment:
Inconsistent visibility modifier. This method is declared as `protected`
while the same method in `SelectorDataDecisionMaker` (line 27) and
`PluginDataDecisionMaker` (line 27) are `public`. For consistency across the
class hierarchy, all implementations should use the same visibility modifier,
preferably `public` since the abstract method in the parent class
`AbstractMatchDecisionMaker` is not explicitly marked with an access modifier
(default package-private).
```suggestion
public boolean shouldContinue(RuleData data) {
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java:
##########
@@ -92,71 +96,56 @@ public abstract class AbstractShenyuPlugin implements
ShenyuPlugin {
public Mono<Void> execute(final ServerWebExchange exchange, final
ShenyuPluginChain chain) {
initCacheConfig();
final String pluginName = named();
- PluginData pluginData =
BaseDataCache.getInstance().obtainPluginData(pluginName);
- // early exit
- if (Objects.isNull(pluginData) || !pluginData.getEnabled()) {
- return chain.execute(exchange);
- }
final String path = getRawPath(exchange);
- List<SelectorData> selectors =
BaseDataCache.getInstance().obtainSelectorData(pluginName);
- if (CollectionUtils.isEmpty(selectors)) {
- return handleSelectorIfNull(pluginName, exchange, chain);
+
+ PluginDataDecisionMaker pluginDataDecisionMaker = new
PluginDataDecisionMaker();
Review Comment:
Creating a new `PluginDataDecisionMaker` instance on every request is
inefficient. These DecisionMaker instances are stateless and should be created
once as class fields (similar to how other components are reused) to avoid
unnecessary object allocation on each request. The same issue applies to
`SelectorDataDecisionMaker` (line 107) and `RuleDataDecisionMaker` (line 124).
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java:
##########
@@ -37,6 +37,10 @@
import org.apache.shenyu.plugin.base.cache.BaseDataCache;
import org.apache.shenyu.plugin.base.cache.MatchDataCache;
import org.apache.shenyu.plugin.base.condition.strategy.MatchStrategyFactory;
+import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
Review Comment:
Unused import `PluginDataHandler`. This import is not used anywhere in the
class and should be removed.
```suggestion
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/provider/RuleDataProvider.java:
##########
@@ -0,0 +1,15 @@
+package org.apache.shenyu.plugin.base.provider;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
Review Comment:
Unused import `SelectorData`. This import is not used anywhere in the class
and should be removed.
```suggestion
```
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/provider/RuleDataProvider.java:
##########
@@ -0,0 +1,15 @@
+package org.apache.shenyu.plugin.base.provider;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.base.cache.BaseDataCache;
+
+import java.util.Collections;
+import java.util.List;
+
+public class RuleDataProvider implements DataProvider<RuleData> {
+ @Override
+ public List<RuleData> getData(String ruleName) {
+ List<RuleData> data =
BaseDataCache.getInstance().obtainRuleData(ruleName);
+ return data != null ? data : Collections.emptyList();
+ }
+}
Review Comment:
Missing class-level and method-level documentation. This new public class
should include Javadoc explaining its purpose and how it fits into the data
provider pattern.
##########
shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/maker/AbstractMatchDecisionMaker.java:
##########
@@ -0,0 +1,27 @@
+package org.apache.shenyu.plugin.base.maker;
+
+import org.apache.shenyu.common.dto.BaseData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.base.provider.DataProvider;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public abstract class AbstractMatchDecisionMaker<T extends BaseData> {
+ private final DataProvider<T> dataProvider;
+
+ protected AbstractMatchDecisionMaker(DataProvider<T> dataProvider) {
+ this.dataProvider = dataProvider;
+ }
+
+ public List<T> getData(String key) {
+ return dataProvider.getData(key);
+ }
+
+ protected abstract Mono<Void> handleEmpty(String pluginName,
ServerWebExchange exchange, ShenyuPluginChain chain);
+
+ protected abstract T matchData(ServerWebExchange exchange, List<T>
dataList, String path);
+
Review Comment:
Missing class-level and method-level documentation. This new public abstract
class should include Javadoc explaining its purpose, the template method
pattern it implements, and detailed documentation for each abstract method
describing their responsibilities and expected behavior.
```suggestion
/**
* Abstract base class for making match decisions in plugins using the
Template Method pattern.
* <p>
* This class provides a template for processing data matching logic in
plugins. Subclasses are expected
* to implement the abstract methods to define specific behaviors for
handling empty data, matching data,
* and determining whether processing should continue.
* </p>
*
* <p>
* The Template Method pattern is used here to allow subclasses to override
certain steps of the algorithm
* without changing its structure.
* </p>
*
* @param <T> the type of data to be matched, extending {@link BaseData}
*/
public abstract class AbstractMatchDecisionMaker<T extends BaseData> {
private final DataProvider<T> dataProvider;
/**
* Constructs an AbstractMatchDecisionMaker with the specified data
provider.
*
* @param dataProvider the data provider used to retrieve data for
matching
*/
protected AbstractMatchDecisionMaker(DataProvider<T> dataProvider) {
this.dataProvider = dataProvider;
}
/**
* Retrieves a list of data associated with the given key.
*
* @param key the key used to retrieve data
* @return a list of data objects associated with the key
*/
public List<T> getData(String key) {
return dataProvider.getData(key);
}
/**
* Handles the scenario when no matching data is found for the given
plugin.
*
* @param pluginName the name of the plugin
* @param exchange the current server web exchange
* @param chain the plugin chain to continue processing
* @return a {@link Mono} that completes when the handling is done
*/
protected abstract Mono<Void> handleEmpty(String pluginName,
ServerWebExchange exchange, ShenyuPluginChain chain);
/**
* Matches the appropriate data from the provided list based on the
exchange and path.
*
* @param exchange the current server web exchange
* @param dataList the list of data to match against
* @param path the request path to use for matching
* @return the matched data object, or {@code null} if no match is found
*/
protected abstract T matchData(ServerWebExchange exchange, List<T>
dataList, String path);
/**
* Determines whether processing should continue based on the matched
data.
*
* @param data the matched data object
* @return {@code true} if processing should continue, {@code false}
otherwise
*/
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]