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 3e06a6481b fix(sync): fully replace websocket snapshots (#7094)
3e06a6481b is described below
commit 3e06a6481b25d36dad1865549644ecbe5ede57dd
Author: Liming Deng <[email protected]>
AuthorDate: Thu Oct 1 06:30:09 2026 +0800
fix(sync): fully replace websocket snapshots (#7094)
---
.../shenyu/admin/listener/DataChangedListener.java | 44 ++++++++++++++++++
.../shenyu/admin/listener/DataChangedEvent.java | 25 +++++++++++
.../admin/listener/DataChangedEventDispatcher.java | 18 +++++---
.../websocket/WebsocketDataChangedListener.java | 52 ++++++++++++++++++++++
.../admin/service/impl/AppAuthServiceImpl.java | 5 +++
.../admin/service/impl/SyncDataServiceImpl.java | 7 +--
.../listener/DataChangedEventDispatcherTest.java | 50 ++++++++++-----------
.../WebsocketDataChangedListenerTest.java | 31 +++++++++++++
.../shenyu/admin/service/AppAuthServiceTest.java | 16 +++++++
.../shenyu/admin/service/SyncDataServiceTest.java | 33 +++++++++++++-
.../plugin/sign/cache/SignAuthDataCache.java | 7 +++
.../sign/subscriber/SignAuthDataSubscriber.java | 5 +++
.../subscriber/SignAuthDataSubscriberTest.java | 11 +++++
.../websocket/handler/AbstractDataHandler.java | 16 +++----
.../data/websocket/handler/PluginDataHandler.java | 1 +
.../data/websocket/handler/RuleDataHandler.java | 1 +
.../websocket/handler/SelectorDataHandler.java | 1 +
.../websocket/handler/PluginDataHandlerTest.java | 19 ++++++--
.../websocket/handler/RuleDataHandlerTest.java | 11 +++--
.../websocket/handler/SelectorDataHandlerTest.java | 11 +++--
.../handler/WebsocketDataHandlerTest.java | 2 +
21 files changed, 310 insertions(+), 56 deletions(-)
diff --git
a/shenyu-admin-listener/shenyu-admin-listener-api/src/main/java/org/apache/shenyu/admin/listener/DataChangedListener.java
b/shenyu-admin-listener/shenyu-admin-listener-api/src/main/java/org/apache/shenyu/admin/listener/DataChangedListener.java
index 01b149a11a..e31e83b642 100644
---
a/shenyu-admin-listener/shenyu-admin-listener-api/src/main/java/org/apache/shenyu/admin/listener/DataChangedListener.java
+++
b/shenyu-admin-listener/shenyu-admin-listener-api/src/main/java/org/apache/shenyu/admin/listener/DataChangedListener.java
@@ -44,6 +44,17 @@ public interface DataChangedListener {
default void onAppAuthChanged(List<AppAuthData> changed, DataEventTypeEnum
eventType) {
}
+ /**
+ * Invoke this method when AppAuth was received for a known namespace.
+ *
+ * @param changed changed data
+ * @param eventType event type
+ * @param namespaceId namespace id
+ */
+ default void onAppAuthChanged(List<AppAuthData> changed, DataEventTypeEnum
eventType, String namespaceId) {
+ onAppAuthChanged(changed, eventType);
+ }
+
/**
* invoke this method when Plugin was received.
*
@@ -53,6 +64,17 @@ public interface DataChangedListener {
default void onPluginChanged(List<PluginData> changed, DataEventTypeEnum
eventType) {
}
+ /**
+ * Invoke this method when Plugin was received for a known namespace.
+ *
+ * @param changed changed data
+ * @param eventType event type
+ * @param namespaceId namespace id
+ */
+ default void onPluginChanged(List<PluginData> changed, DataEventTypeEnum
eventType, String namespaceId) {
+ onPluginChanged(changed, eventType);
+ }
+
/**
* invoke this method when Selector was received.
*
@@ -62,6 +84,17 @@ public interface DataChangedListener {
default void onSelectorChanged(List<SelectorData> changed,
DataEventTypeEnum eventType) {
}
+ /**
+ * Invoke this method when Selector was received for a known namespace.
+ *
+ * @param changed changed data
+ * @param eventType event type
+ * @param namespaceId namespace id
+ */
+ default void onSelectorChanged(List<SelectorData> changed,
DataEventTypeEnum eventType, String namespaceId) {
+ onSelectorChanged(changed, eventType);
+ }
+
/**
* On meta data changed.
*
@@ -81,6 +114,17 @@ public interface DataChangedListener {
default void onRuleChanged(List<RuleData> changed, DataEventTypeEnum
eventType) {
}
+ /**
+ * Invoke this method when Rule was received for a known namespace.
+ *
+ * @param changed changed data
+ * @param eventType event type
+ * @param namespaceId namespace id
+ */
+ default void onRuleChanged(List<RuleData> changed, DataEventTypeEnum
eventType, String namespaceId) {
+ onRuleChanged(changed, eventType);
+ }
+
/**
* invoke this method when ProxySelector was changed.
*
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
index e89105528e..7a14a33faa 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
@@ -39,6 +39,8 @@ public class DataChangedEvent extends ApplicationEvent {
private final ConfigGroupEnum groupKey;
+ private final String namespaceId;
+
/**
* Instantiates a new Data changed event.
*
@@ -47,9 +49,23 @@ public class DataChangedEvent extends ApplicationEvent {
* @param source the source
*/
public DataChangedEvent(final ConfigGroupEnum groupKey, final
DataEventTypeEnum type, final List<?> source) {
+ this(groupKey, type, source, null);
+ }
+
+ /**
+ * Instantiates a new data changed event for a known namespace.
+ *
+ * @param groupKey group key
+ * @param type event type
+ * @param source source data
+ * @param namespaceId namespace id
+ */
+ public DataChangedEvent(final ConfigGroupEnum groupKey, final
DataEventTypeEnum type,
+ final List<?> source, final String namespaceId) {
super(source.stream().filter(Objects::nonNull).collect(Collectors.toList()));
this.eventType = type;
this.groupKey = groupKey;
+ this.namespaceId = namespaceId;
}
/**
@@ -75,4 +91,13 @@ public class DataChangedEvent extends ApplicationEvent {
return this.groupKey;
}
+ /**
+ * Gets namespace id.
+ *
+ * @return namespace id, or null when it was not supplied
+ */
+ public String getNamespaceId() {
+ return namespaceId;
+ }
+
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcher.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcher.java
index a13594ea72..0962677b25 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcher.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcher.java
@@ -80,23 +80,29 @@ public class DataChangedEventDispatcher implements
ApplicationListener<DataChang
LOG.info("received DataChangedEvent, not master, pass");
return;
}
- final int size = event.getSource() instanceof java.util.Collection
? ((java.util.Collection<?>) event.getSource()).size() : 1;
- LOG.info("received DataChangedEvent, group={}, size={}, type={}",
event.getGroupKey(), size, event.getEventType());
+ final int size = event.getSource() instanceof java.util.Collection
+ ? ((java.util.Collection<?>) event.getSource()).size() : 1;
+ LOG.info("received DataChangedEvent, group={}, size={}, type={}",
+ event.getGroupKey(), size, event.getEventType());
if (LOG.isDebugEnabled()) {
LOG.debug("received DataChangedEvent payload: {}",
JsonUtils.toJson(event));
}
switch (event.getGroupKey()) {
case APP_AUTH:
- listener.onAppAuthChanged((List<AppAuthData>)
event.getSource(), event.getEventType());
+ listener.onAppAuthChanged((List<AppAuthData>)
event.getSource(),
+ event.getEventType(), event.getNamespaceId());
break;
case PLUGIN:
- listener.onPluginChanged((List<PluginData>)
event.getSource(), event.getEventType());
+ listener.onPluginChanged((List<PluginData>)
event.getSource(),
+ event.getEventType(), event.getNamespaceId());
break;
case RULE:
- listener.onRuleChanged((List<RuleData>) event.getSource(),
event.getEventType());
+ listener.onRuleChanged((List<RuleData>) event.getSource(),
+ event.getEventType(), event.getNamespaceId());
break;
case SELECTOR:
- listener.onSelectorChanged((List<SelectorData>)
event.getSource(), event.getEventType());
+ listener.onSelectorChanged((List<SelectorData>)
event.getSource(),
+ event.getEventType(), event.getNamespaceId());
break;
case META_DATA:
listener.onMetaDataChanged((List<MetaData>)
event.getSource(), event.getEventType());
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListener.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListener.java
index bb0f2601b0..f9f28e4acc 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListener.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListener.java
@@ -35,6 +35,7 @@ import org.apache.shenyu.common.enums.ConfigGroupEnum;
import org.apache.shenyu.common.enums.DataEventTypeEnum;
import org.apache.shenyu.common.utils.GsonUtils;
+import java.util.Collections;
import java.util.List;
/**
@@ -65,6 +66,16 @@ public class WebsocketDataChangedListener implements
DataChangedListener {
}
}
+ @Override
+ public void onPluginChanged(final List<PluginData> changed, final
DataEventTypeEnum eventType,
+ final String namespaceId) {
+ if (CollectionUtils.isEmpty(changed)) {
+ sendEmptySnapshot(ConfigGroupEnum.PLUGIN, eventType, namespaceId);
+ return;
+ }
+ onPluginChanged(changed, eventType);
+ }
+
@Override
public void onSelectorChanged(
final List<SelectorData> selectorDataList, final DataEventTypeEnum
eventType) {
@@ -86,6 +97,16 @@ public class WebsocketDataChangedListener implements
DataChangedListener {
}
}
+ @Override
+ public void onSelectorChanged(final List<SelectorData> changed, final
DataEventTypeEnum eventType,
+ final String namespaceId) {
+ if (CollectionUtils.isEmpty(changed)) {
+ sendEmptySnapshot(ConfigGroupEnum.SELECTOR, eventType,
namespaceId);
+ return;
+ }
+ onSelectorChanged(changed, eventType);
+ }
+
@Override
public void onRuleChanged(
final List<RuleData> ruleDataList, final DataEventTypeEnum
eventType) {
@@ -106,6 +127,16 @@ public class WebsocketDataChangedListener implements
DataChangedListener {
}
}
+ @Override
+ public void onRuleChanged(final List<RuleData> changed, final
DataEventTypeEnum eventType,
+ final String namespaceId) {
+ if (CollectionUtils.isEmpty(changed)) {
+ sendEmptySnapshot(ConfigGroupEnum.RULE, eventType, namespaceId);
+ return;
+ }
+ onRuleChanged(changed, eventType);
+ }
+
@Override
public void onAppAuthChanged(
final List<AppAuthData> appAuthDataList, final DataEventTypeEnum
eventType) {
@@ -127,6 +158,27 @@ public class WebsocketDataChangedListener implements
DataChangedListener {
}
}
+ @Override
+ public void onAppAuthChanged(final List<AppAuthData> changed, final
DataEventTypeEnum eventType,
+ final String namespaceId) {
+ if (CollectionUtils.isEmpty(changed)) {
+ sendEmptySnapshot(ConfigGroupEnum.APP_AUTH, eventType,
namespaceId);
+ return;
+ }
+ onAppAuthChanged(changed, eventType);
+ }
+
+ private void sendEmptySnapshot(final ConfigGroupEnum group, final
DataEventTypeEnum eventType,
+ final String namespaceId) {
+ if (StringUtils.isBlank(namespaceId)
+ || (eventType != DataEventTypeEnum.REFRESH && eventType !=
DataEventTypeEnum.MYSELF)) {
+ return;
+ }
+ WebsocketData<Object> websocketData =
+ new WebsocketData<>(group.name(), eventType.name(),
Collections.emptyList());
+ WebsocketCollector.send(namespaceId,
GsonUtils.getInstance().toJson(websocketData), eventType);
+ }
+
@Override
public void onMetaDataChanged(
final List<MetaData> metaDataList, final DataEventTypeEnum
eventType) {
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AppAuthServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AppAuthServiceImpl.java
index 0aeb8373d5..8fae8407de 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AppAuthServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AppAuthServiceImpl.java
@@ -277,6 +277,11 @@ public class AppAuthServiceImpl implements AppAuthService {
@Override
public ShenyuAdminResult syncDataByNamespaceId(final String namespaceId) {
List<AppAuthDO> appAuthDOList =
appAuthMapper.selectAllByNamespaceId(namespaceId);
+ if (CollectionUtils.isEmpty(appAuthDOList)) {
+ eventPublisher.publishEvent(new
DataChangedEvent(ConfigGroupEnum.APP_AUTH,
+ DataEventTypeEnum.REFRESH, Collections.emptyList(),
namespaceId));
+ return ShenyuAdminResult.success();
+ }
return syncData(appAuthDOList);
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SyncDataServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SyncDataServiceImpl.java
index f36d12e9b6..1ceedc9b79 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SyncDataServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SyncDataServiceImpl.java
@@ -147,13 +147,14 @@ public class SyncDataServiceImpl implements
SyncDataService {
List<PluginData> pluginDataList =
namespacePluginService.listAll(namespaceId);
- eventPublisher.publishEvent(new
DataChangedEvent(ConfigGroupEnum.PLUGIN, type, pluginDataList));
+ eventPublisher.publishEvent(new
DataChangedEvent(ConfigGroupEnum.PLUGIN, type, pluginDataList, namespaceId));
List<SelectorData> selectorDataList =
selectorService.listAllByNamespaceId(namespaceId);
- eventPublisher.publishEvent(new
DataChangedEvent(ConfigGroupEnum.SELECTOR, type, selectorDataList));
+ eventPublisher.publishEvent(
+ new DataChangedEvent(ConfigGroupEnum.SELECTOR, type,
selectorDataList, namespaceId));
List<RuleData> ruleDataList =
ruleService.listAllByNamespaceId(namespaceId);
- eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE,
type, ruleDataList));
+ eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE,
type, ruleDataList, namespaceId));
metaDataService.syncDataByNamespaceId(namespaceId);
discoveryService.syncDataByNamespaceId(namespaceId);
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcherTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcherTest.java
index fad86580f1..52236191bd 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcherTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/DataChangedEventDispatcherTest.java
@@ -123,10 +123,10 @@ public final class DataChangedEventDispatcherTest {
ConfigGroupEnum configGroupEnum = ConfigGroupEnum.APP_AUTH;
DataChangedEvent dataChangedEvent = new
DataChangedEvent(configGroupEnum, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(httpLongPollingDataChangedListener,
times(1)).onAppAuthChanged(anyList(), any());
- verify(nacosDataChangedListener, times(1)).onAppAuthChanged(anyList(),
any());
- verify(websocketDataChangedListener,
times(1)).onAppAuthChanged(anyList(), any());
- verify(zookeeperDataChangedListener,
times(1)).onAppAuthChanged(anyList(), any());
+ verify(httpLongPollingDataChangedListener,
times(1)).onAppAuthChanged(anyList(), any(), any());
+ verify(nacosDataChangedListener, times(1)).onAppAuthChanged(anyList(),
any(), any());
+ verify(websocketDataChangedListener,
times(1)).onAppAuthChanged(anyList(), any(), any());
+ verify(zookeeperDataChangedListener,
times(1)).onAppAuthChanged(anyList(), any(), any());
}
/**
@@ -139,10 +139,10 @@ public final class DataChangedEventDispatcherTest {
ConfigGroupEnum configGroupEnum = ConfigGroupEnum.PLUGIN;
DataChangedEvent dataChangedEvent = new
DataChangedEvent(configGroupEnum, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(httpLongPollingDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
- verify(nacosDataChangedListener, times(1)).onPluginChanged(anyList(),
any());
- verify(websocketDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
- verify(zookeeperDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
+ verify(httpLongPollingDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
+ verify(nacosDataChangedListener, times(1)).onPluginChanged(anyList(),
any(), any());
+ verify(websocketDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
+ verify(zookeeperDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
}
/**
@@ -155,10 +155,10 @@ public final class DataChangedEventDispatcherTest {
ConfigGroupEnum configGroupEnum = ConfigGroupEnum.RULE;
DataChangedEvent dataChangedEvent = new
DataChangedEvent(configGroupEnum, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(httpLongPollingDataChangedListener,
times(1)).onRuleChanged(anyList(), any());
- verify(nacosDataChangedListener, times(1)).onRuleChanged(anyList(),
any());
- verify(websocketDataChangedListener,
times(1)).onRuleChanged(anyList(), any());
- verify(zookeeperDataChangedListener,
times(1)).onRuleChanged(anyList(), any());
+ verify(httpLongPollingDataChangedListener,
times(1)).onRuleChanged(anyList(), any(), any());
+ verify(nacosDataChangedListener, times(1)).onRuleChanged(anyList(),
any(), any());
+ verify(websocketDataChangedListener,
times(1)).onRuleChanged(anyList(), any(), any());
+ verify(zookeeperDataChangedListener,
times(1)).onRuleChanged(anyList(), any(), any());
}
/**
@@ -171,10 +171,10 @@ public final class DataChangedEventDispatcherTest {
ConfigGroupEnum configGroupEnum = ConfigGroupEnum.SELECTOR;
DataChangedEvent dataChangedEvent = new
DataChangedEvent(configGroupEnum, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(httpLongPollingDataChangedListener,
times(1)).onSelectorChanged(anyList(), any());
- verify(nacosDataChangedListener,
times(1)).onSelectorChanged(anyList(), any());
- verify(websocketDataChangedListener,
times(1)).onSelectorChanged(anyList(), any());
- verify(zookeeperDataChangedListener,
times(1)).onSelectorChanged(anyList(), any());
+ verify(httpLongPollingDataChangedListener,
times(1)).onSelectorChanged(anyList(), any(), any());
+ verify(nacosDataChangedListener,
times(1)).onSelectorChanged(anyList(), any(), any());
+ verify(websocketDataChangedListener,
times(1)).onSelectorChanged(anyList(), any(), any());
+ verify(zookeeperDataChangedListener,
times(1)).onSelectorChanged(anyList(), any(), any());
}
/**
@@ -274,10 +274,10 @@ public final class DataChangedEventDispatcherTest {
when(clusterProperties.isEnabled()).thenReturn(false);
DataChangedEvent dataChangedEvent = new
DataChangedEvent(ConfigGroupEnum.PLUGIN, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(httpLongPollingDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
- verify(nacosDataChangedListener, times(1)).onPluginChanged(anyList(),
any());
- verify(websocketDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
- verify(zookeeperDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
+ verify(httpLongPollingDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
+ verify(nacosDataChangedListener, times(1)).onPluginChanged(anyList(),
any(), any());
+ verify(websocketDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
+ verify(zookeeperDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
}
/**
@@ -292,7 +292,7 @@ public final class DataChangedEventDispatcherTest {
ReflectionTestUtils.setField(dataChangedEventDispatcher, "listeners",
Collections.unmodifiableList(orderedListeners));
DataChangedEvent dataChangedEvent = new
DataChangedEvent(ConfigGroupEnum.PLUGIN, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(nacosDataChangedListener, never()).onPluginChanged(anyList(),
any());
+ verify(nacosDataChangedListener, never()).onPluginChanged(anyList(),
any(), any());
}
/**
@@ -306,9 +306,9 @@ public final class DataChangedEventDispatcherTest {
field.set(dataChangedEventDispatcher, null);
DataChangedEvent dataChangedEvent = new
DataChangedEvent(ConfigGroupEnum.PLUGIN, null, new ArrayList<>());
dataChangedEventDispatcher.onApplicationEvent(dataChangedEvent);
- verify(nacosDataChangedListener, times(1)).onPluginChanged(anyList(),
any());
- verify(httpLongPollingDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
- verify(websocketDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
- verify(zookeeperDataChangedListener,
times(1)).onPluginChanged(anyList(), any());
+ verify(nacosDataChangedListener, times(1)).onPluginChanged(anyList(),
any(), any());
+ verify(httpLongPollingDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
+ verify(websocketDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
+ verify(zookeeperDataChangedListener,
times(1)).onPluginChanged(anyList(), any(), any());
}
}
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListenerTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListenerTest.java
index 4c7ee9f500..3e1fb5a074 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListenerTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/websocket/WebsocketDataChangedListenerTest.java
@@ -196,6 +196,29 @@ public final class WebsocketDataChangedListenerTest {
}
}
+ /**
+ * test empty namespace snapshots.
+ */
+ @Test
+ public void testEmptyNamespaceSnapshots() {
+ String namespaceId = "namespace-id";
+ try (MockedStatic<WebsocketCollector> mockedStatic =
mockStatic(WebsocketCollector.class)) {
+ websocketDataChangedListener.onPluginChanged(
+ Collections.emptyList(), DataEventTypeEnum.MYSELF,
namespaceId);
+ websocketDataChangedListener.onSelectorChanged(
+ Collections.emptyList(), DataEventTypeEnum.MYSELF,
namespaceId);
+ websocketDataChangedListener.onRuleChanged(
+ Collections.emptyList(), DataEventTypeEnum.MYSELF,
namespaceId);
+ websocketDataChangedListener.onAppAuthChanged(
+ Collections.emptyList(), DataEventTypeEnum.REFRESH,
namespaceId);
+
+ verifyEmptySnapshot(mockedStatic, namespaceId, "PLUGIN",
DataEventTypeEnum.MYSELF);
+ verifyEmptySnapshot(mockedStatic, namespaceId, "SELECTOR",
DataEventTypeEnum.MYSELF);
+ verifyEmptySnapshot(mockedStatic, namespaceId, "RULE",
DataEventTypeEnum.MYSELF);
+ verifyEmptySnapshot(mockedStatic, namespaceId, "APP_AUTH",
DataEventTypeEnum.REFRESH);
+ }
+ }
+
/**
* test MetaData.
*/
@@ -366,6 +389,14 @@ public final class WebsocketDataChangedListenerTest {
}
}
+ private void verifyEmptySnapshot(final MockedStatic<WebsocketCollector>
mockedStatic, final String namespaceId,
+ final String groupType, final
DataEventTypeEnum eventType) {
+ String message = String.format(
+ "{\"groupType\":\"%s\",\"eventType\":\"%s\",\"data\":[]}",
groupType, eventType.name());
+ mockedStatic.verify(() -> WebsocketCollector.send(
+ eq(namespaceId), argThat(actualMsg -> jsonEquals(message,
actualMsg)), eq(eventType)));
+ }
+
private void initMetaDataList() {
MetaData metaData = new MetaData();
metaData.setAppName("axiba");
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/AppAuthServiceTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/AppAuthServiceTest.java
index 8c86f7c729..3715aa1c29 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/AppAuthServiceTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/AppAuthServiceTest.java
@@ -43,6 +43,7 @@ import
org.apache.shenyu.admin.service.impl.AppAuthServiceImpl;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
import org.apache.shenyu.common.constant.AdminConstants;
import org.apache.shenyu.common.dto.AppAuthData;
+import org.apache.shenyu.common.enums.ConfigGroupEnum;
import org.apache.shenyu.common.exception.CommonErrorCode;
import org.apache.shenyu.common.utils.SignUtils;
import org.apache.shenyu.common.utils.UUIDUtils;
@@ -300,6 +301,21 @@ public final class AppAuthServiceTest {
verify(eventPublisher, times(1)).publishEvent(any());
}
+ @Test
+ public void testSyncEmptyDataByNamespaceId() {
+ String namespaceId = "namespace-id";
+
when(appAuthMapper.selectAllByNamespaceId(namespaceId)).thenReturn(Collections.emptyList());
+
+ appAuthService.syncDataByNamespaceId(namespaceId);
+
+ ArgumentCaptor<DataChangedEvent> eventCaptor =
ArgumentCaptor.forClass(DataChangedEvent.class);
+ verify(eventPublisher).publishEvent(eventCaptor.capture());
+ DataChangedEvent event = eventCaptor.getValue();
+ assertEquals(ConfigGroupEnum.APP_AUTH, event.getGroupKey());
+ assertEquals(namespaceId, event.getNamespaceId());
+ assertEquals(Collections.emptyList(), event.getSource());
+ }
+
private void testApplyCreateParameterError() {
testApplyCreateAppNameBlank();
testApplyCreateMissingPathsWhenOpen();
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/SyncDataServiceTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/SyncDataServiceTest.java
index 4af22988d1..1ca6d8c448 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/SyncDataServiceTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/SyncDataServiceTest.java
@@ -17,20 +17,23 @@
package org.apache.shenyu.admin.service;
+import org.apache.shenyu.admin.listener.DataChangedEvent;
import org.apache.shenyu.admin.model.result.ShenyuAdminResult;
import org.apache.shenyu.admin.model.vo.NamespacePluginVO;
import org.apache.shenyu.admin.service.impl.SyncDataServiceImpl;
+import org.apache.shenyu.admin.service.support.AiProxyRealKeyResolver;
import org.apache.shenyu.common.dto.ConditionData;
import org.apache.shenyu.common.dto.PluginData;
import org.apache.shenyu.common.dto.RuleData;
import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.enums.ConfigGroupEnum;
import org.apache.shenyu.common.enums.DataEventTypeEnum;
import org.apache.shenyu.common.enums.OperatorEnum;
import org.apache.shenyu.common.enums.ParamTypeEnum;
import org.apache.shenyu.common.utils.DateUtils;
-import static org.hamcrest.Matchers.lessThanOrEqualTo;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -40,12 +43,17 @@ import
org.springframework.context.ApplicationEventPublisher;
import java.time.LocalDateTime;
import java.util.Collections;
+import java.util.List;
import static
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.lessThanOrEqualTo;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.BDDMockito.given;
-import org.apache.shenyu.admin.service.support.AiProxyRealKeyResolver;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
/**
* test for SyncDataService.
@@ -127,6 +135,27 @@ public final class SyncDataServiceTest {
assertThat(syncDataService.syncPluginData(pluginVO.getId()),
lessThanOrEqualTo(false));
}
+ @Test
+ public void syncAllByNamespaceIdPublishesEmptySnapshotsTest() {
+ String namespaceId = "namespace-id";
+
given(this.namespacePluginService.listAll(namespaceId)).willReturn(Collections.emptyList());
+
given(this.selectorService.listAllByNamespaceId(namespaceId)).willReturn(Collections.emptyList());
+
given(this.ruleService.listAllByNamespaceId(namespaceId)).willReturn(Collections.emptyList());
+
+
assertTrue(syncDataService.syncAllByNamespaceId(DataEventTypeEnum.MYSELF,
namespaceId));
+
+ ArgumentCaptor<DataChangedEvent> eventCaptor =
ArgumentCaptor.forClass(DataChangedEvent.class);
+ verify(eventPublisher, times(3)).publishEvent(eventCaptor.capture());
+ List<DataChangedEvent> events = eventCaptor.getAllValues();
+ assertEquals(ConfigGroupEnum.PLUGIN, events.get(0).getGroupKey());
+ assertEquals(ConfigGroupEnum.SELECTOR, events.get(1).getGroupKey());
+ assertEquals(ConfigGroupEnum.RULE, events.get(2).getGroupKey());
+ events.forEach(event -> {
+ assertEquals(namespaceId, event.getNamespaceId());
+ assertTrue(event.getSource().isEmpty());
+ });
+ }
+
/**
* build mock PluginData.
diff --git
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/cache/SignAuthDataCache.java
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/cache/SignAuthDataCache.java
index 822d843d32..fcb4e1712e 100644
---
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/cache/SignAuthDataCache.java
+++
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/cache/SignAuthDataCache.java
@@ -63,6 +63,13 @@ public final class SignAuthDataCache {
public void removeAuthData(final AppAuthData data) {
AUTH_MAP.remove(data.getAppKey());
}
+
+ /**
+ * Clean all auth data.
+ */
+ public void cleanAuthData() {
+ AUTH_MAP.clear();
+ }
/**
* Obtain auth data app auth data.
diff --git
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriber.java
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriber.java
index d360786f76..ee83757548 100644
---
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriber.java
+++
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriber.java
@@ -35,4 +35,9 @@ public class SignAuthDataSubscriber implements
AuthDataSubscriber {
public void unSubscribe(final AppAuthData appAuthData) {
SignAuthDataCache.getInstance().removeAuthData(appAuthData);
}
+
+ @Override
+ public void refresh() {
+ SignAuthDataCache.getInstance().cleanAuthData();
+ }
}
diff --git
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/test/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriberTest.java
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/test/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriberTest.java
index d56e3dab07..39704c933d 100644
---
a/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/test/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriberTest.java
+++
b/shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/test/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriberTest.java
@@ -60,4 +60,15 @@ public class SignAuthDataSubscriberTest {
signAuthDataSubscriber.unSubscribe(appAuthData);
assertNull(SignAuthDataCache.getInstance().obtainAuthData("D9FD95F496C9495DB5604222A13C3D08"));
}
+
+ @Test
+ void refresh() {
+ AppAuthData appAuthData = new AppAuthData();
+ appAuthData.setAppKey("stale-key");
+ signAuthDataSubscriber.onSubscribe(appAuthData);
+
+ signAuthDataSubscriber.refresh();
+
+
assertNull(SignAuthDataCache.getInstance().obtainAuthData("stale-key"));
+ }
}
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/AbstractDataHandler.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/AbstractDataHandler.java
index 48188dd67a..a75e443ee1 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/AbstractDataHandler.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/AbstractDataHandler.java
@@ -17,6 +17,7 @@
package org.apache.shenyu.plugin.sync.data.websocket.handler;
+import java.util.Collections;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
@@ -61,23 +62,22 @@ public abstract class AbstractDataHandler<T> implements
DataHandler {
@Override
public void handle(final String json, final String eventType) {
List<T> dataList = convert(json);
-
- if (CollectionUtils.isEmpty(dataList)) {
- return;
- }
-
DataEventTypeEnum eventTypeEnum =
DataEventTypeEnum.acquireByName(eventType);
switch (eventTypeEnum) {
case REFRESH:
case MYSELF:
- doRefresh(dataList);
+ doRefresh(CollectionUtils.isEmpty(dataList) ?
Collections.emptyList() : dataList);
break;
case UPDATE:
case CREATE:
- doUpdate(dataList);
+ if (CollectionUtils.isNotEmpty(dataList)) {
+ doUpdate(dataList);
+ }
break;
case DELETE:
- doDelete(dataList);
+ if (CollectionUtils.isNotEmpty(dataList)) {
+ doDelete(dataList);
+ }
break;
default:
break;
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandler.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandler.java
index 40e4b22719..719414fe54 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandler.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandler.java
@@ -41,6 +41,7 @@ public class PluginDataHandler extends
AbstractDataHandler<PluginData> {
@Override
protected void doRefresh(final List<PluginData> dataList) {
+ pluginDataSubscriber.refreshPluginDataAll();
pluginDataSubscriber.onPluginRefresh(dataList);
}
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandler.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandler.java
index 31e8ff697b..a447b19ee9 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandler.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandler.java
@@ -40,6 +40,7 @@ public class RuleDataHandler extends
AbstractDataHandler<RuleData> {
@Override
protected void doRefresh(final List<RuleData> dataList) {
+ pluginDataSubscriber.refreshRuleDataAll();
pluginDataSubscriber.onRuleRefresh(dataList);
}
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandler.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandler.java
index 8682485636..7db231633e 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandler.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandler.java
@@ -41,6 +41,7 @@ public class SelectorDataHandler extends
AbstractDataHandler<SelectorData> {
@Override
protected void doRefresh(final List<SelectorData> dataList) {
+ pluginDataSubscriber.refreshSelectorDataAll();
pluginDataSubscriber.onSelectorRefresh(dataList);
}
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandlerTest.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandlerTest.java
index 978d49030f..54e5626173 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandlerTest.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/PluginDataHandlerTest.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.plugin.sync.data.websocket.handler;
import com.google.gson.Gson;
import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.enums.DataEventTypeEnum;
import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -31,7 +32,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
public final class PluginDataHandlerTest {
@@ -60,24 +60,35 @@ public final class PluginDataHandlerTest {
public void testDoRefresh() {
List<PluginData> pluginDataList = createFakePluginDataObjects(3);
pluginDataHandler.doRefresh(pluginDataList);
+ verify(subscriber).refreshPluginDataAll();
verify(subscriber).onPluginRefresh(pluginDataList);
}
@ParameterizedTest
@ValueSource(strings = {"REFRESH", "MYSELF"})
- void testRefreshEventsUseOnlyTheBatchCallback(final String eventType) {
+ void testRefreshEventsClearThenUseBatchCallback(final String eventType) {
List<PluginData> batch = createFakePluginDataObjects(2);
pluginDataHandler.handle(new Gson().toJson(batch), eventType);
+ verify(subscriber).refreshPluginDataAll();
verify(subscriber).onPluginRefresh(batch);
verifyNoMoreInteractions(subscriber);
}
@ParameterizedTest
@ValueSource(strings = {"REFRESH", "MYSELF"})
- void testEmptyRefreshDoesNotCallSubscriber(final String eventType) {
+ void testEmptyRefreshClearsSnapshot(final String eventType) {
pluginDataHandler.handle("[]", eventType);
- verifyNoInteractions(subscriber);
+ verify(subscriber).refreshPluginDataAll();
+ verify(subscriber).onPluginRefresh(java.util.Collections.emptyList());
+ verifyNoMoreInteractions(subscriber);
+ }
+
+ @Test
+ public void testEmptySnapshotStillClearsCachedData() {
+ pluginDataHandler.handle("[]", DataEventTypeEnum.MYSELF.name());
+
+ verify(subscriber).refreshPluginDataAll();
}
@Test
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandlerTest.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandlerTest.java
index 648483b3e5..fbb524845b 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandlerTest.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/RuleDataHandlerTest.java
@@ -33,7 +33,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
public final class RuleDataHandlerTest {
@@ -65,24 +64,28 @@ public final class RuleDataHandlerTest {
public void testDoRefresh() {
List<RuleData> ruleDataList = createFakeRuleDateObjects(3);
ruleDataHandler.doRefresh(ruleDataList);
+ verify(subscriber).refreshRuleDataAll();
verify(subscriber).onRuleRefresh(ruleDataList);
}
@ParameterizedTest
@ValueSource(strings = {"REFRESH", "MYSELF"})
- void testRefreshEventsUseOnlyTheBatchCallback(final String eventType) {
+ void testRefreshEventsClearThenUseBatchCallback(final String eventType) {
List<RuleData> batch = createFakeRuleDateObjects(2);
ruleDataHandler.handle(new Gson().toJson(batch), eventType);
+ verify(subscriber).refreshRuleDataAll();
verify(subscriber).onRuleRefresh(batch);
verifyNoMoreInteractions(subscriber);
}
@ParameterizedTest
@ValueSource(strings = {"REFRESH", "MYSELF"})
- void testEmptyRefreshDoesNotCallSubscriber(final String eventType) {
+ void testEmptyRefreshClearsSnapshot(final String eventType) {
ruleDataHandler.handle("[]", eventType);
- verifyNoInteractions(subscriber);
+ verify(subscriber).refreshRuleDataAll();
+ verify(subscriber).onRuleRefresh(java.util.Collections.emptyList());
+ verifyNoMoreInteractions(subscriber);
}
@Test
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandlerTest.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandlerTest.java
index e58e7037ee..7a5e8833e8 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandlerTest.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/SelectorDataHandlerTest.java
@@ -33,7 +33,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
public final class SelectorDataHandlerTest {
@@ -65,25 +64,29 @@ public final class SelectorDataHandlerTest {
public void testDoRefresh() {
List<SelectorData> selectorDataList = createFakeSelectorDataObjects(3);
selectorDataHandler.doRefresh(selectorDataList);
+ verify(subscriber).refreshSelectorDataAll();
verify(subscriber).onSelectorRefresh(selectorDataList);
}
@ParameterizedTest
@ValueSource(strings = {"REFRESH", "MYSELF"})
- void testRefreshEventsUseOnlyTheBatchCallback(final String eventType) {
+ void testRefreshEventsClearThenUseBatchCallback(final String eventType) {
List<SelectorData> batch = createFakeSelectorDataObjects(2);
batch.forEach(data -> data.setContinued(true));
selectorDataHandler.handle(new Gson().toJson(batch), eventType);
+ verify(subscriber).refreshSelectorDataAll();
verify(subscriber).onSelectorRefresh(batch);
verifyNoMoreInteractions(subscriber);
}
@ParameterizedTest
@ValueSource(strings = {"REFRESH", "MYSELF"})
- void testEmptyRefreshDoesNotCallSubscriber(final String eventType) {
+ void testEmptyRefreshClearsSnapshot(final String eventType) {
selectorDataHandler.handle("[]", eventType);
- verifyNoInteractions(subscriber);
+ verify(subscriber).refreshSelectorDataAll();
+
verify(subscriber).onSelectorRefresh(java.util.Collections.emptyList());
+ verifyNoMoreInteractions(subscriber);
}
@Test
diff --git
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/WebsocketDataHandlerTest.java
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/WebsocketDataHandlerTest.java
index 4dca4ea295..afec30bcee 100644
---
a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/WebsocketDataHandlerTest.java
+++
b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/test/java/org/apache/shenyu/plugin/sync/data/websocket/handler/WebsocketDataHandlerTest.java
@@ -64,6 +64,7 @@ public final class WebsocketDataHandlerTest {
public void testPluginRefreshExecutor() {
String json = getJson();
websocketDataHandler.executor(ConfigGroupEnum.PLUGIN, json,
DataEventTypeEnum.REFRESH.name());
+ Mockito.verify(pluginDataSubscriber).refreshPluginDataAll();
List<PluginData> pluginDataList = new
PluginDataHandler(pluginDataSubscriber).convert(json);
Mockito.verify(pluginDataSubscriber).onPluginRefresh(pluginDataList);
}
@@ -72,6 +73,7 @@ public final class WebsocketDataHandlerTest {
public void testPluginMyselfExecutor() {
String json = getJson();
websocketDataHandler.executor(ConfigGroupEnum.PLUGIN, json,
DataEventTypeEnum.MYSELF.name());
+ Mockito.verify(pluginDataSubscriber).refreshPluginDataAll();
List<PluginData> pluginDataList = new
PluginDataHandler(pluginDataSubscriber).convert(json);
Mockito.verify(pluginDataSubscriber).onPluginRefresh(pluginDataList);
}