This is an automated email from the ASF dual-hosted git repository.
yx9o pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git
The following commit(s) were added to refs/heads/rocketmq-studio by this push:
new 34c8a204 fix: reject updates for missing data sources
34c8a204 is described below
commit 34c8a204b1d317b407330746bdf3f6e3515dcd40
Author: yx9o <[email protected]>
AuthorDate: Sat Jul 25 15:29:10 2026 +0800
fix: reject updates for missing data sources
---
.../settings/InMemorySettingsRepository.java | 5 ++++
.../studio/settings/SettingsRepository.java | 2 ++
.../rocketmq/studio/settings/SettingsService.java | 6 +++-
.../settings/InMemorySettingsRepositoryTest.java | 32 ++++++++++++++++------
.../studio/settings/SettingsServiceTest.java | 20 ++++++++++++--
5 files changed, 53 insertions(+), 12 deletions(-)
diff --git
a/server/src/main/java/com/rocketmq/studio/settings/InMemorySettingsRepository.java
b/server/src/main/java/com/rocketmq/studio/settings/InMemorySettingsRepository.java
index d3c01e43..82cd03c2 100644
---
a/server/src/main/java/com/rocketmq/studio/settings/InMemorySettingsRepository.java
+++
b/server/src/main/java/com/rocketmq/studio/settings/InMemorySettingsRepository.java
@@ -65,6 +65,11 @@ public class InMemorySettingsRepository implements
SettingsRepository {
return dataSource;
}
+ @Override
+ public boolean replaceDataSource(DataSourceVO dataSource) {
+ return dataSources.replace(dataSource.getKey(), dataSource) != null;
+ }
+
@Override
public void deleteDataSource(String key) {
dataSources.remove(key);
diff --git
a/server/src/main/java/com/rocketmq/studio/settings/SettingsRepository.java
b/server/src/main/java/com/rocketmq/studio/settings/SettingsRepository.java
index 70e08a71..49b3e8ee 100644
--- a/server/src/main/java/com/rocketmq/studio/settings/SettingsRepository.java
+++ b/server/src/main/java/com/rocketmq/studio/settings/SettingsRepository.java
@@ -30,6 +30,8 @@ public interface SettingsRepository {
DataSourceVO saveDataSource(DataSourceVO dataSource);
+ boolean replaceDataSource(DataSourceVO dataSource);
+
void deleteDataSource(String key);
Optional<DataSourceVO> findDataSourceByKey(String key);
diff --git
a/server/src/main/java/com/rocketmq/studio/settings/SettingsService.java
b/server/src/main/java/com/rocketmq/studio/settings/SettingsService.java
index 2c2db875..3dce8aff 100644
--- a/server/src/main/java/com/rocketmq/studio/settings/SettingsService.java
+++ b/server/src/main/java/com/rocketmq/studio/settings/SettingsService.java
@@ -16,6 +16,7 @@
*/
package com.rocketmq.studio.settings;
+import com.rocketmq.studio.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -66,7 +67,10 @@ public class SettingsService {
public DataSourceVO updateDataSource(DataSourceVO dataSource) {
log.info("Updating data source: {}", dataSource.getKey());
- return settingsRepository.saveDataSource(dataSource);
+ if (!settingsRepository.replaceDataSource(dataSource)) {
+ throw new BusinessException(404, "Data source not found: " +
dataSource.getKey());
+ }
+ return dataSource;
}
diff --git
a/server/src/test/java/com/rocketmq/studio/settings/InMemorySettingsRepositoryTest.java
b/server/src/test/java/com/rocketmq/studio/settings/InMemorySettingsRepositoryTest.java
index d1d06f60..c811eff7 100644
---
a/server/src/test/java/com/rocketmq/studio/settings/InMemorySettingsRepositoryTest.java
+++
b/server/src/test/java/com/rocketmq/studio/settings/InMemorySettingsRepositoryTest.java
@@ -25,7 +25,7 @@ class InMemorySettingsRepositoryTest {
private final InMemorySettingsRepository repository = new
InMemorySettingsRepository();
@Test
- void saveDataSourceShouldSupportCreateUpdateAndDeleteByKey() {
+ void saveDataSourceShouldSupportCreateAndDeleteByKey() {
DataSourceVO dataSource = DataSourceVO.builder()
.key("source-1")
.name("Prometheus")
@@ -38,17 +38,31 @@ class InMemorySettingsRepositoryTest {
assertThat(repository.findDataSourceByKey("source-1")).containsSame(dataSource);
assertThat(repository.findAllDataSources()).containsExactly(dataSource);
- dataSource.setName("Updated Prometheus");
- repository.saveDataSource(dataSource);
-
- assertThat(repository.findDataSourceByKey("source-1"))
- .get()
- .extracting(DataSourceVO::getName)
- .isEqualTo("Updated Prometheus");
-
repository.deleteDataSource("source-1");
assertThat(repository.findDataSourceByKey("source-1")).isEmpty();
assertThat(repository.findAllDataSources()).isEmpty();
}
+
+ @Test
+ void replaceDataSourceShouldUpdateExistingEntry() {
+ DataSourceVO existing =
DataSourceVO.builder().key("source-1").name("Prometheus").build();
+ DataSourceVO replacement =
DataSourceVO.builder().key("source-1").name("Updated Prometheus").build();
+ repository.saveDataSource(existing);
+
+ boolean replaced = repository.replaceDataSource(replacement);
+
+ assertThat(replaced).isTrue();
+
assertThat(repository.findAllDataSources()).containsExactly(replacement);
+ }
+
+ @Test
+ void replaceDataSourceShouldNotInsertUnknownEntry() {
+ DataSourceVO replacement =
DataSourceVO.builder().key("missing").name("Unexpected DS").build();
+
+ boolean replaced = repository.replaceDataSource(replacement);
+
+ assertThat(replaced).isFalse();
+ assertThat(repository.findAllDataSources()).isEmpty();
+ }
}
diff --git
a/server/src/test/java/com/rocketmq/studio/settings/SettingsServiceTest.java
b/server/src/test/java/com/rocketmq/studio/settings/SettingsServiceTest.java
index 024a9a75..af2d8de8 100644
--- a/server/src/test/java/com/rocketmq/studio/settings/SettingsServiceTest.java
+++ b/server/src/test/java/com/rocketmq/studio/settings/SettingsServiceTest.java
@@ -16,6 +16,7 @@
*/
package com.rocketmq.studio.settings;
+import com.rocketmq.studio.common.exception.BusinessException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@@ -27,6 +28,7 @@ import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
@@ -188,13 +190,27 @@ class SettingsServiceTest {
void updateDataSourceShouldDelegateToRepository() {
DataSourceVO input = DataSourceVO.builder().key("ds-1").name("Updated
DS").type("rocketmq")
.url("updated-host:9876").build();
-
when(settingsRepository.saveDataSource(any(DataSourceVO.class))).thenReturn(input);
+ when(settingsRepository.replaceDataSource(input)).thenReturn(true);
DataSourceVO result = settingsService.updateDataSource(input);
assertThat(result.getKey()).isEqualTo("ds-1");
assertThat(result.getName()).isEqualTo("Updated DS");
- verify(settingsRepository).saveDataSource(input);
+ verify(settingsRepository).replaceDataSource(input);
+ }
+
+ @Test
+ void updateDataSourceShouldRejectUnknownKey() {
+ SettingsService service = new SettingsService(new
InMemorySettingsRepository());
+ DataSourceVO input =
DataSourceVO.builder().key("missing").name("Unexpected DS").type("rocketmq")
+ .url("unexpected-host:9876").build();
+
+ assertThatThrownBy(() -> service.updateDataSource(input))
+ .isInstanceOf(BusinessException.class)
+ .hasMessage("Data source not found: missing")
+ .extracting("code")
+ .isEqualTo(404);
+ assertThat(service.listDataSources()).isEmpty();
}
@Test