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 e2b3bec845 fix: Invalid discoveryHandlerId can persist broken 
discovery upstream rows (#6530)
e2b3bec845 is described below

commit e2b3bec8456a77f90cfe014d7c6d3738aa886fd0
Author: hengyuss <[email protected]>
AuthorDate: Fri Sep 18 12:30:21 2026 +0800

    fix: Invalid discoveryHandlerId can persist broken discovery upstream rows 
(#6530)
    
    * fix: Invalid discoveryHandlerId can persist broken discovery upstream rows
    
    * trigger CI
    
    * fix: add test
    
    ---------
    
    Co-authored-by: zhengpeng <[email protected]>
    Co-authored-by: Liming Deng <[email protected]>
---
 .../admin/model/dto/DiscoveryUpstreamDTO.java      |   2 +
 .../DiscoveryUpstreamControllerTest.java           | 146 +++++++++++++++++++++
 2 files changed, 148 insertions(+)

diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/DiscoveryUpstreamDTO.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/DiscoveryUpstreamDTO.java
index dcceeb0bf4..cefe1d230f 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/DiscoveryUpstreamDTO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/DiscoveryUpstreamDTO.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.admin.model.dto;
 
+import org.apache.shenyu.admin.mapper.DiscoveryHandlerMapper;
 import org.apache.shenyu.admin.mapper.DiscoveryUpstreamMapper;
 import org.apache.shenyu.admin.mapper.NamespaceMapper;
 import org.apache.shenyu.admin.validation.annotation.Existed;
@@ -43,6 +44,7 @@ public class DiscoveryUpstreamDTO implements Serializable {
      * discoveryHandler id.
      */
     @NotBlank(message = "discoveryHandlerId can't be null")
+    @Existed(provider = DiscoveryHandlerMapper.class, message = 
"discoveryHandlerId is not existed")
     private String discoveryHandlerId;
 
     /**
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/DiscoveryUpstreamControllerTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/DiscoveryUpstreamControllerTest.java
new file mode 100644
index 0000000000..847ae23a90
--- /dev/null
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/DiscoveryUpstreamControllerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.controller;
+
+import org.apache.shenyu.admin.exception.ExceptionHandlers;
+import org.apache.shenyu.admin.mapper.DiscoveryHandlerMapper;
+import org.apache.shenyu.admin.mapper.DiscoveryUpstreamMapper;
+import org.apache.shenyu.admin.mapper.NamespaceMapper;
+import org.apache.shenyu.admin.model.dto.DiscoveryUpstreamDTO;
+import org.apache.shenyu.admin.service.DiscoveryUpstreamService;
+import org.apache.shenyu.admin.spring.SpringBeanUtils;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Collections;
+import java.util.List;
+
+import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
+import static org.hamcrest.Matchers.containsString;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public final class DiscoveryUpstreamControllerTest {
+
+    private MockMvc mockMvc;
+
+    @InjectMocks
+    private DiscoveryUpstreamController discoveryUpstreamController;
+
+    @Mock
+    private DiscoveryUpstreamService discoveryUpstreamService;
+
+    @Mock
+    private DiscoveryHandlerMapper discoveryHandlerMapper;
+
+    @Mock
+    private DiscoveryUpstreamMapper discoveryUpstreamMapper;
+
+    @Mock
+    private NamespaceMapper namespaceMapper;
+
+    @BeforeEach
+    public void setUp() {
+        this.mockMvc = 
MockMvcBuilders.standaloneSetup(discoveryUpstreamController)
+                .setControllerAdvice(new ExceptionHandlers(null))
+                .build();
+        
SpringBeanUtils.getInstance().setApplicationContext(mock(ConfigurableApplicationContext.class));
+    }
+
+    @Test
+    public void testCreateWithNonExistentDiscoveryHandlerIdShouldFail() throws 
Exception {
+        DiscoveryUpstreamDTO dto = buildDTO("nonExistentHandlerId");
+        
when(SpringBeanUtils.getInstance().getBean(DiscoveryHandlerMapper.class)).thenReturn(discoveryHandlerMapper);
+        
when(discoveryHandlerMapper.existed("nonExistentHandlerId")).thenReturn(false);
+        
when(SpringBeanUtils.getInstance().getBean(DiscoveryUpstreamMapper.class)).thenReturn(discoveryUpstreamMapper);
+        when(discoveryUpstreamMapper.existed(dto.getId())).thenReturn(false);
+        
when(SpringBeanUtils.getInstance().getBean(NamespaceMapper.class)).thenReturn(namespaceMapper);
+        
when(namespaceMapper.existed(SYS_DEFAULT_NAMESPACE_ID)).thenReturn(true);
+
+        this.mockMvc.perform(MockMvcRequestBuilders.post("/discovery-upstream")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(GsonUtils.getInstance().toJson(dto)))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.message", 
containsString("discoveryHandlerId is not existed")));
+    }
+
+    @Test
+    public void testCreateWithExistentDiscoveryHandlerIdShouldSucceed() throws 
Exception {
+        DiscoveryUpstreamDTO dto = buildDTO("existentHandlerId");
+        
when(SpringBeanUtils.getInstance().getBean(DiscoveryHandlerMapper.class)).thenReturn(discoveryHandlerMapper);
+        
when(discoveryHandlerMapper.existed("existentHandlerId")).thenReturn(true);
+        
when(SpringBeanUtils.getInstance().getBean(DiscoveryUpstreamMapper.class)).thenReturn(discoveryUpstreamMapper);
+        when(discoveryUpstreamMapper.existed(dto.getId())).thenReturn(false);
+        
when(SpringBeanUtils.getInstance().getBean(NamespaceMapper.class)).thenReturn(namespaceMapper);
+        
when(namespaceMapper.existed(SYS_DEFAULT_NAMESPACE_ID)).thenReturn(true);
+        
given(discoveryUpstreamService.createOrUpdate(dto)).willReturn("success");
+
+        this.mockMvc.perform(MockMvcRequestBuilders.post("/discovery-upstream")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(GsonUtils.getInstance().toJson(dto)))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.code").value(200));
+    }
+
+    @Test
+    public void testUpdateWithExistentDiscoveryHandlerIdShouldSucceed() throws 
Exception {
+        DiscoveryUpstreamDTO dto = buildDTO("existentHandlerId");
+        List<DiscoveryUpstreamDTO> dtoList = Collections.singletonList(dto);
+        
when(SpringBeanUtils.getInstance().getBean(DiscoveryHandlerMapper.class)).thenReturn(discoveryHandlerMapper);
+        
when(discoveryHandlerMapper.existed("existentHandlerId")).thenReturn(true);
+        
when(SpringBeanUtils.getInstance().getBean(DiscoveryUpstreamMapper.class)).thenReturn(discoveryUpstreamMapper);
+        when(discoveryUpstreamMapper.existed(dto.getId())).thenReturn(false);
+        
when(SpringBeanUtils.getInstance().getBean(NamespaceMapper.class)).thenReturn(namespaceMapper);
+        
when(namespaceMapper.existed(SYS_DEFAULT_NAMESPACE_ID)).thenReturn(true);
+        given(discoveryUpstreamService.updateBatch("existentHandlerId", 
dtoList)).willReturn(0);
+
+        
this.mockMvc.perform(MockMvcRequestBuilders.put("/discovery-upstream/{discoveryHandlerId}",
 "existentHandlerId")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(GsonUtils.getInstance().toJson(dtoList)))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.code").value(200));
+    }
+
+    private DiscoveryUpstreamDTO buildDTO(final String discoveryHandlerId) {
+        DiscoveryUpstreamDTO dto = new DiscoveryUpstreamDTO();
+        dto.setDiscoveryHandlerId(discoveryHandlerId);
+        dto.setNamespaceId(SYS_DEFAULT_NAMESPACE_ID);
+        dto.setUrl("http://localhost:8080";);
+        dto.setStatus(0);
+        dto.setWeight(50);
+        dto.setProps("{}");
+        return dto;
+    }
+}

Reply via email to