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");
+    }
 }

Reply via email to