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 bca690634a fix(admin): skip orphan discovery bindings during full sync
(#7250)
bca690634a is described below
commit bca690634a0e22955480cca0a7a35dbeb5555632
Author: Liming Deng <[email protected]>
AuthorDate: Thu Oct 1 06:28:33 2026 +0800
fix(admin): skip orphan discovery bindings during full sync (#7250)
---
.../service/impl/DiscoveryUpstreamServiceImpl.java | 18 +++++++++-
.../service/DiscoveryUpstreamServiceTest.java | 39 ++++++++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryUpstreamServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryUpstreamServiceImpl.java
index fca9a06012..943ba7386d 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryUpstreamServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryUpstreamServiceImpl.java
@@ -46,6 +46,8 @@ import org.apache.shenyu.admin.utils.Assert;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
import org.apache.shenyu.common.dto.DiscoverySyncData;
import org.apache.shenyu.common.dto.DiscoveryUpstreamData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
@@ -63,6 +65,8 @@ import java.util.stream.Collectors;
@Service
public class DiscoveryUpstreamServiceImpl implements DiscoveryUpstreamService {
+ private static final Logger LOG =
LoggerFactory.getLogger(DiscoveryUpstreamServiceImpl.class);
+
private final DiscoveryUpstreamMapper discoveryUpstreamMapper;
private final DiscoveryHandlerMapper discoveryHandlerMapper;
@@ -192,18 +196,30 @@ public class DiscoveryUpstreamServiceImpl implements
DiscoveryUpstreamService {
private List<DiscoverySyncData> buildSyncData(final
List<DiscoveryHandlerDO> discoveryHandlerDOS) {
return discoveryHandlerDOS.stream().map(d -> {
DiscoveryRelDO discoveryRelDO =
discoveryRelMapper.selectByDiscoveryHandlerId(d.getId());
+ if (Objects.isNull(discoveryRelDO)) {
+ LOG.warn("Skipping discovery handler {} without a relation",
d.getId());
+ return null;
+ }
DiscoverySyncData discoverySyncData = new DiscoverySyncData();
discoverySyncData.setPluginName(discoveryRelDO.getPluginName());
if (StringUtils.hasLength(discoveryRelDO.getSelectorId())) {
String selectorId = discoveryRelDO.getSelectorId();
discoverySyncData.setSelectorId(selectorId);
SelectorDO selectorDO = selectorMapper.selectById(selectorId);
+ if (Objects.isNull(selectorDO)) {
+ LOG.warn("Skipping discovery handler {} with missing
selector {}", d.getId(), selectorId);
+ return null;
+ }
discoverySyncData.setSelectorName(selectorDO.getSelectorName());
discoverySyncData.setNamespaceId(selectorDO.getNamespaceId());
} else {
String proxySelectorId = discoveryRelDO.getProxySelectorId();
discoverySyncData.setSelectorId(proxySelectorId);
ProxySelectorDO proxySelectorDO =
proxySelectorMapper.selectById(proxySelectorId);
+ if (Objects.isNull(proxySelectorDO)) {
+ LOG.warn("Skipping discovery handler {} with missing proxy
selector {}", d.getId(), proxySelectorId);
+ return null;
+ }
discoverySyncData.setSelectorName(proxySelectorDO.getName());
discoverySyncData.setNamespaceId(proxySelectorDO.getNamespaceId());
}
@@ -211,7 +227,7 @@ public class DiscoveryUpstreamServiceImpl implements
DiscoveryUpstreamService {
.map(DiscoveryTransfer.INSTANCE::mapToData).collect(Collectors.toList());
discoverySyncData.setUpstreamDataList(discoveryUpstreamDataList);
return discoverySyncData;
- }).collect(Collectors.toList());
+ }).filter(Objects::nonNull).collect(Collectors.toList());
}
@Override
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DiscoveryUpstreamServiceTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DiscoveryUpstreamServiceTest.java
index cd1de5a753..d8a5176663 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DiscoveryUpstreamServiceTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DiscoveryUpstreamServiceTest.java
@@ -176,6 +176,45 @@ public final class DiscoveryUpstreamServiceTest {
assertEquals(dataList.size(), list.size());
}
+ @Test
+ public void testListAllSkipsOrphansAndKeepsValidBindings() {
+ DiscoveryHandlerDO noRelation = buildDiscoveryHandlerDO();
+ noRelation.setId("no-relation");
+ DiscoveryHandlerDO missingSelector = buildDiscoveryHandlerDO();
+ missingSelector.setId("missing-selector");
+ DiscoveryHandlerDO missingProxy = buildDiscoveryHandlerDO();
+ missingProxy.setId("missing-proxy");
+ DiscoveryHandlerDO validSelector = buildDiscoveryHandlerDO();
+ validSelector.setId("valid-selector");
+ DiscoveryHandlerDO validProxy = buildDiscoveryHandlerDO();
+ validProxy.setId("valid-proxy");
+
when(discoveryHandlerMapper.selectAll()).thenReturn(List.of(noRelation,
missingSelector, validSelector, missingProxy, validProxy));
+
when(discoveryRelMapper.selectByDiscoveryHandlerId("no-relation")).thenReturn(null);
+ DiscoveryRelDO staleSelectorRel = buildDiscoveryRelDO();
+ staleSelectorRel.setSelectorId("deleted-selector");
+
when(discoveryRelMapper.selectByDiscoveryHandlerId("missing-selector")).thenReturn(staleSelectorRel);
+ DiscoveryRelDO staleProxyRel = buildDiscoveryRelDO();
+ staleProxyRel.setProxySelectorId("deleted-proxy");
+
when(discoveryRelMapper.selectByDiscoveryHandlerId("missing-proxy")).thenReturn(staleProxyRel);
+ DiscoveryRelDO selectorRel = buildDiscoveryRelDO();
+ selectorRel.setSelectorId("selector_1");
+
when(discoveryRelMapper.selectByDiscoveryHandlerId("valid-selector")).thenReturn(selectorRel);
+
when(selectorMapper.selectById("selector_1")).thenReturn(buildSelectorDO());
+ when(selectorMapper.selectById("deleted-selector")).thenReturn(null);
+ DiscoveryRelDO proxyRel = buildDiscoveryRelDO();
+ proxyRel.setProxySelectorId("proxy_1");
+
when(discoveryRelMapper.selectByDiscoveryHandlerId("valid-proxy")).thenReturn(proxyRel);
+
when(proxySelectorMapper.selectById("proxy_1")).thenReturn(buildProxySelectorDO());
+ when(proxySelectorMapper.selectById("deleted-proxy")).thenReturn(null);
+ List<DiscoverySyncData> result = discoveryUpstreamService.listAll();
+ assertEquals(2, result.size());
+ assertEquals("selector_1", result.get(0).getSelectorId());
+ assertEquals("proxy_1", result.get(1).getSelectorId());
+ verify(discoveryUpstreamMapper,
never()).selectByDiscoveryHandlerId("no-relation");
+ verify(discoveryUpstreamMapper,
never()).selectByDiscoveryHandlerId("missing-selector");
+ verify(discoveryUpstreamMapper,
never()).selectByDiscoveryHandlerId("missing-proxy");
+ }
+
@Test
public void testListAllData() {
List<DiscoveryUpstreamDO> list =
Collections.singletonList(buildDiscoveryUpstreamDO(""));