This is an automated email from the ASF dual-hosted git repository.
dengliming 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 436f82b6fd fix: prevent NPE in Dubbo ingress upstream parsing (#6860)
(#7059)
436f82b6fd is described below
commit 436f82b6fd20b38ab3d96d923973fc5efcee9089
Author: Southern <[email protected]>
AuthorDate: Fri Sep 18 15:13:09 2026 +0800
fix: prevent NPE in Dubbo ingress upstream parsing (#6860) (#7059)
* fix: prevent NPE in Dubbo ingress upstream parsing (#6860)
Guard null path backends and missing upstream protocol annotations in
DubboIngressParser, and add focused tests for null
annotations, missing annotation keys, and null backends.
* fix: prevent NPE in Dubbo ingress upstream parsing (#6860)
Guard null path backends and missing upstream protocol annotations in
DubboIngressParser. Add regression tests for null
annotations and null path backends.
---------
Co-authored-by: Liming Deng <[email protected]>
---
.../shenyu/k8s/parser/DubboIngressParser.java | 6 ++-
.../shenyu/k8s/parser/DubboIngressParserTest.java | 49 ++++++++++++++++++++++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
index 4a2e077dcd..72425a2b93 100644
---
a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
+++
b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/DubboIngressParser.java
@@ -332,12 +332,14 @@ public class DubboIngressParser implements
K8sResourceParser<V1Ingress> {
private List<DubboUpstream> parseUpstream(final V1HTTPIngressPath path,
final String namespace, final Map<String, String> annotations) {
List<DubboUpstream> upstreamList = new ArrayList<>();
- if (Objects.nonNull(path) &&
Objects.nonNull(path.getBackend().getService()) &&
Objects.nonNull(path.getBackend().getService().getName())) {
+ if (Objects.nonNull(path) && Objects.nonNull(path.getBackend())
+ && Objects.nonNull(path.getBackend().getService()) &&
Objects.nonNull(path.getBackend().getService().getName())) {
String serviceName = path.getBackend().getService().getName();
V1Endpoints v1Endpoints =
endpointsLister.namespace(namespace).get(serviceName);
List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
String[] protocols = null;
- if (Objects.nonNull(annotations) &&
annotations.containsKey(IngressConstants.UPSTREAMS_PROTOCOL_ANNOTATION_KEY)) {
+ if (Objects.nonNull(annotations) &&
annotations.containsKey(IngressConstants.UPSTREAMS_PROTOCOL_ANNOTATION_KEY)
+ &&
Objects.nonNull(annotations.get(IngressConstants.UPSTREAMS_PROTOCOL_ANNOTATION_KEY)))
{
protocols =
annotations.get(IngressConstants.UPSTREAMS_PROTOCOL_ANNOTATION_KEY).split(",");
}
if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
diff --git
a/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/DubboIngressParserTest.java
b/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/DubboIngressParserTest.java
index b53291f074..6907b28777 100644
---
a/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/DubboIngressParserTest.java
+++
b/shenyu-kubernetes-controller/src/test/java/org/apache/shenyu/k8s/parser/DubboIngressParserTest.java
@@ -32,9 +32,11 @@ import
org.apache.shenyu.common.dto.convert.selector.DubboUpstream;
import org.apache.shenyu.common.utils.GsonUtils;
import org.apache.shenyu.k8s.common.IngressConstants;
import org.apache.shenyu.k8s.common.ShenyuMemoryConfig;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -51,6 +53,11 @@ import static org.mockito.Mockito.when;
*/
public class DubboIngressParserTest {
+ private static final String NAMESPACE = "test-namespace";
+
+ private static final String SERVICE_NAME = "backend-service";
+
+
private Lister<V1Service> serviceLister;
private Indexer<V1Endpoints> endpointsIndexer;
@@ -152,4 +159,46 @@ public class DubboIngressParserTest {
List<DubboUpstream> upstreams = assertDoesNotThrow(() ->
parseAndGetUpstreams(annotations));
assertNotNull(upstreams);
}
+
+ @Test
+ public void shouldParseIngressWhenAnnotationsAreNull() {
+ ShenyuMemoryConfig config = assertDoesNotThrow(() ->
createParser().parse(
+ createIngress(null, Collections.emptyMap(), true), null));
+
+ String handle =
config.getRouteConfigList().get(0).getSelectorData().getHandle();
+ List<DubboUpstream> upstreams =
GsonUtils.getInstance().fromList(handle, DubboUpstream.class);
+ assertEquals(1, upstreams.size());
+ assertEquals("dubbo://", upstreams.get(0).getProtocol());
+ }
+
+ @Test
+ public void shouldIgnorePathWithNullBackend() {
+ ShenyuMemoryConfig config = Assertions.assertDoesNotThrow(() ->
createParser().parse(
+ createIngress(null, Collections.emptyMap(), false), null));
+
+ Assertions.assertEquals(1, config.getRouteConfigList().size());
+ Assertions.assertEquals("[]",
config.getRouteConfigList().get(0).getSelectorData().getHandle());
+ }
+
+ private DubboIngressParser createParser() {
+ Indexer<V1Service> serviceIndexer = mock(Indexer.class);
+ Indexer<V1Endpoints> endpointsIndexer = mock(Indexer.class);
+ V1Endpoints endpoints = new V1EndpointsBuilder().withSubsets(new
V1EndpointSubsetBuilder()
+ .withAddresses(new
V1EndpointAddress().ip("127.0.0.1")).build()).build();
+ when(endpointsIndexer.getByKey(NAMESPACE + "/" +
SERVICE_NAME)).thenReturn(endpoints);
+ return new DubboIngressParser(new Lister<>(serviceIndexer), new
Lister<>(endpointsIndexer));
+ }
+
+ private V1Ingress createIngress(final Map<String, String> annotations,
final Map<String, String> labels,
+ final boolean withBackend) {
+ V1HTTPIngressPathBuilder pathBuilder = new
V1HTTPIngressPathBuilder().withPath("/test").withPathType("Prefix");
+ if (withBackend) {
+
pathBuilder.withNewBackend().withNewService().withName(SERVICE_NAME).withNewPort().withNumber(8080)
+ .endPort().endService().endBackend();
+ }
+ return new
V1IngressBuilder().withNewMetadata().withName("test-ingress").withNamespace(NAMESPACE)
+ .withAnnotations(annotations).withLabels(labels).endMetadata()
+ .withNewSpec().withRules(new
V1IngressRuleBuilder().withNewHttp().withPaths(pathBuilder.build())
+ .endHttp().build()).endSpec().build();
+ }
}