This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new d5a1218eb0 fix(kubernetes-controller): guard against null contextPath
annotation in ContextPathParser (#7031)
d5a1218eb0 is described below
commit d5a1218eb0d8f5d19b3671046c3bd5b5925aa23b
Author: Shatrughan Rai <[email protected]>
AuthorDate: Thu Oct 8 07:00:16 2026 +0530
fix(kubernetes-controller): guard against null contextPath annotation in
ContextPathParser (#7031)
* fix(kubernetes-controller): guard against null contextPath annotation in
ContextPathParser
When the 'shenyu.apache.org/plugin-context-path-path' annotation is absent,
annotations.get() returns null, and null + '/**' produced the literal string
'null/**' as a path pattern rule condition. This created phantom rules that
never matched real traffic.
- Add null guard: skip rule creation when context-path annotation is not set
- Change getRuleConditionList and createRuleData to accept String params
directly
- Add test cases for missing annotation, present annotation, and empty
string
Closes #6863
Signed-off-by: Shatrughan Rai <[email protected]>
* fix(kubernetes-controller): apply review comments for PR #7031
Re-add the setter - scoped to the non-null contextPath
add an assertion in testParseWithContextPathAnnotation that the produced
ContextMappingRuleHandle.getContextPath()
Closes #6863
Signed-off-by: Shatrughan Rai <[email protected]>
* fix(admin-api-v2): apply review comments for PR #7031
Skip the entire route configuration when contextPath is null
update the regression test to expect no ContextPath route configs.
Closes #6863
* fix(kubernetes-controller): treat empty string context-path annotation as
blank
Align testParseWithEmptyStringContextPathAnnotation with implementation:
an empty annotation value is treated as blank (same as missing) and
produces no route configs, consistent with the null-guard behavior
from issue #6863.
Signed-off-by: Shatrughan Rai <[email protected]>
* test(kubernetes-controller): add empty string context-path annotation
test with conflict resolution
Add testParseWithEmptyStringContextPathAnnotation to verify that an
empty-string annotation value is treated as blank (same as missing),
producing no route configs. Consistent with the StringUtils.isBlank
guard in ContextPathParser.
Resolved merge conflict with upstream master (PR #7175 by wy471x) which
rewrote ContextPathParserTest with a different structure; kept upstream's
6 tests and added this 7th test.
Signed-off-by: Shatrughan Rai <[email protected]>
---------
Signed-off-by: Shatrughan Rai <[email protected]>
Co-authored-by: aias00 <[email protected]>
---
.../shenyu/k8s/parser/ContextPathParser.java | 32 ++++++++++++----------
.../shenyu/k8s/parser/ContextPathParserTest.java | 23 ++++++++++++++++
2 files changed, 41 insertions(+), 14 deletions(-)
diff --git
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/ContextPathParser.java
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/ContextPathParser.java
index 555096eb78..f42e86db8b 100644
---
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/ContextPathParser.java
+++
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/ContextPathParser.java
@@ -122,16 +122,20 @@ public class ContextPathParser implements
K8sResourceParser<V1Ingress> {
}
OperatorEnum operator = getOperator(path.getPathType());
ConditionData pathCondition =
createPathCondition(pathPath, operator);
- List<ConditionData> conditionList = new ArrayList<>(2);
+ String contextPath =
annotations.get(IngressConstants.PLUGIN_CONTEXT_PATH_PATH);
+ if (Objects.isNull(contextPath)) {
+ continue;
+ }
+ List<ConditionData> conditionListWithPath = new
ArrayList<>(2);
if (Objects.nonNull(hostCondition)) {
- conditionList.add(hostCondition);
+ conditionListWithPath.add(hostCondition);
}
- conditionList.add(pathCondition);
- SelectorData selectorData = createSelectorData(pathPath,
conditionList);
- ContextMappingRuleHandle contextMappingRuleHandle =
createContextMappingRuleHandle(annotations);
- List<RuleData> ruleDataList = new ArrayList<>();
- List<ConditionData> ruleConditionList =
getRuleConditionList(annotations);
- RuleData ruleData = createRuleData(annotations,
contextMappingRuleHandle, ruleConditionList);
+ conditionListWithPath.add(pathCondition);
+ SelectorData selectorData = createSelectorData(pathPath,
conditionListWithPath);
+ ContextMappingRuleHandle contextMappingRuleHandle =
createContextMappingRuleHandle(contextPath, annotations);
+ List<ConditionData> ruleConditionList =
getRuleConditionList(contextPath);
+ List<RuleData> ruleDataList = new ArrayList<>(1);
+ RuleData ruleData = createRuleData(contextPath,
contextMappingRuleHandle, ruleConditionList);
ruleDataList.add(ruleData);
res.add(new IngressConfiguration(selectorData,
ruleDataList, null));
}
@@ -231,17 +235,17 @@ public class ContextPathParser implements
K8sResourceParser<V1Ingress> {
.build();
}
- private ContextMappingRuleHandle createContextMappingRuleHandle(final
Map<String, String> annotations) {
+ private ContextMappingRuleHandle createContextMappingRuleHandle(final
String contextPath, final Map<String, String> annotations) {
ContextMappingRuleHandle ruleHandle = new ContextMappingRuleHandle();
-
ruleHandle.setContextPath(annotations.get(IngressConstants.PLUGIN_CONTEXT_PATH_PATH));
+ ruleHandle.setContextPath(contextPath);
ruleHandle.setAddPrefix(annotations.get(IngressConstants.PLUGIN_CONTEXT_PATH_ADD_PREFIX));
ruleHandle.setAddPrefixed(Boolean.parseBoolean(annotations.getOrDefault(IngressConstants.PLUGIN_CONTEXT_PATH_ADD_PREFIXED,
"false")));
return ruleHandle;
}
- private RuleData createRuleData(final Map<String, String> annotations,
final ContextMappingRuleHandle ruleHandle, final List<ConditionData>
ruleConditionList) {
+ private RuleData createRuleData(final String name, final
ContextMappingRuleHandle ruleHandle, final List<ConditionData>
ruleConditionList) {
return RuleData.builder()
-
.name(annotations.get(IngressConstants.PLUGIN_CONTEXT_PATH_PATH))
+ .name(name)
.pluginName(PluginEnum.CONTEXT_PATH.getName())
.matchMode(MatchModeEnum.AND.getCode())
.conditionDataList(ruleConditionList)
@@ -251,12 +255,12 @@ public class ContextPathParser implements
K8sResourceParser<V1Ingress> {
.build();
}
- private List<ConditionData> getRuleConditionList(final Map<String, String>
annotations) {
+ private List<ConditionData> getRuleConditionList(final String contextPath)
{
final List<ConditionData> ruleConditionList = new ArrayList<>();
ConditionData ruleCondition = new ConditionData();
ruleCondition.setOperator(OperatorEnum.PATH_PATTERN.getAlias());
ruleCondition.setParamType(ParamTypeEnum.URI.getName());
-
ruleCondition.setParamValue(annotations.get(IngressConstants.PLUGIN_CONTEXT_PATH_PATH)
+ "/**");
+ ruleCondition.setParamValue(contextPath + "/**");
ruleConditionList.add(ruleCondition);
return ruleConditionList;
}
diff --git
a/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/ContextPathParserTest.java
b/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/ContextPathParserTest.java
index 778875576d..645cefaa81 100644
---
a/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/ContextPathParserTest.java
+++
b/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/ContextPathParserTest.java
@@ -44,6 +44,7 @@ import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -199,4 +200,26 @@ public class ContextPathParserTest {
private V1HTTPIngressPath createPath(final String path, final String
pathType) {
return new
V1HTTPIngressPathBuilder().withPath(path).withPathType(pathType).build();
}
+
+ @Test
+ public void testParseWithEmptyStringContextPathAnnotation() {
+ Map<String, String> annotations = new HashMap<>();
+ annotations.put(IngressConstants.PLUGIN_CONTEXT_PATH_PATH, "");
+
+ V1Ingress ingress = new V1IngressBuilder()
+
.withNewMetadata().withName("test-ingress-empty").withNamespace(NAMESPACE)
+ .withAnnotations(annotations).endMetadata()
+ .withNewSpec().withRules(createRule(null,
createPath("/context", "Prefix"))).endSpec()
+ .withKind("Ingress")
+ .build();
+
+ ShenyuMemoryConfig config = parse(ingress);
+ List<IngressConfiguration> routeConfigList =
config.getRouteConfigList();
+
+ // Empty string is treated as blank (same as missing annotation),
+ // so no route configurations should be produced.
+ assertTrue(
+ Objects.isNull(routeConfigList) || routeConfigList.isEmpty(),
+ "No route configs should be produced when context-path
annotation is empty");
+ }
}