diff --git a/app-builder/plugins/data-mate-knowledge/src/main/java/modelengine/fit/jade/datamate/knowledge/external/DataMateKnowledgeBaseManager.java b/app-builder/plugins/data-mate-knowledge/src/main/java/modelengine/fit/jade/datamate/knowledge/external/DataMateKnowledgeBaseManager.java index 0341270a17..acb7b2f8dc 100644 --- a/app-builder/plugins/data-mate-knowledge/src/main/java/modelengine/fit/jade/datamate/knowledge/external/DataMateKnowledgeBaseManager.java +++ b/app-builder/plugins/data-mate-knowledge/src/main/java/modelengine/fit/jade/datamate/knowledge/external/DataMateKnowledgeBaseManager.java @@ -136,8 +136,9 @@ public DataMateRetrievalResult retrieve(String apiKey, DataMateRetrievalParam pa private KnowledgeException handleException(HttpClientResponseException ex) { int statusCode = ex.statusCode(); - log.error(this.exceptionMap.get(statusCode).getMsg(), ex); - return new KnowledgeException(this.exceptionMap.get(statusCode), ex, ex.getSimpleMessage()); + KnowledgeManagerRetCode retCode = this.exceptionMap.getOrDefault(statusCode, INTERNAL_SERVICE_ERROR); + log.error(retCode.getMsg(), ex); + return new KnowledgeException(retCode, ex, ex.getSimpleMessage()); } private HttpClassicClient getHttpClient() { diff --git a/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/DataMateKnowledgeBaseManagerTest.java b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/DataMateKnowledgeBaseManagerTest.java new file mode 100644 index 0000000000..d873524386 --- /dev/null +++ b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/DataMateKnowledgeBaseManagerTest.java @@ -0,0 +1,111 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved. + * This file is a part of the ModelEngine Project. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +package modelengine.fit.jade.datamate.knowledge; + +import modelengine.fit.http.client.HttpClassicClientResponse; +import modelengine.fitframework.annotation.Fit; +import modelengine.fitframework.test.annotation.MvcTest; +import modelengine.fitframework.test.domain.mvc.MockMvc; +import modelengine.fit.jade.datamate.knowledge.dto.DataMateKnowledgeListQueryParam; +import modelengine.fit.jade.datamate.knowledge.dto.DataMateRetrievalParam; +import modelengine.fit.jade.datamate.knowledge.entity.DataMateKnowledgeEntity; +import modelengine.fit.jade.datamate.knowledge.entity.DataMateKnowledgeListEntity; +import modelengine.fit.jade.datamate.knowledge.entity.DataMateRetrievalChunksEntity; +import modelengine.fit.jade.datamate.knowledge.entity.DataMateRetrievalResult; +import modelengine.fit.jade.datamate.knowledge.external.DataMateKnowledgeBaseManager; +import modelengine.jade.knowledge.exception.KnowledgeException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +/** + * 表示 {@link DataMateKnowledgeBaseManager} 的测试集。 + * + * @author songyongtan + * @since 2026-02-11 + */ +@MvcTest(classes = {MockedDataMateKnowledgeBaseInnerController.class, DataMateKnowledgeBaseManager.class}) +public class DataMateKnowledgeBaseManagerTest { + private String apiKey = "123"; + + @Fit + DataMateKnowledgeBaseManager manager; + + @Fit + private MockMvc mockMvc; + + private HttpClassicClientResponse response; + + @BeforeEach + void setUp() throws Exception { + Field dataMateUrls = manager.getClass().getDeclaredField("dataMateUrls"); + dataMateUrls.setAccessible(true); + Map urls = new HashMap<>(); + urls.put("list", "http://localhost:" + mockMvc.getPort() + "/v2/knowledgeBase"); + urls.put("retrieve", "http://localhost:" + mockMvc.getPort() + "/v2/knowledgebases/query"); + dataMateUrls.set(manager, urls); + } + + @AfterEach + void teardown() throws IOException { + if (this.response != null) { + this.response.close(); + } + } + + @Test + @DisplayName("查询知识库列表成功") + public void shouldOkWhenListRepo() { + DataMateKnowledgeListQueryParam param = DataMateKnowledgeListQueryParam.builder().name("ok").build(); + DataMateKnowledgeListEntity entity = this.manager.listRepos(apiKey, param); + assertThat(entity.getContent().size()).isEqualTo(2); + assertThat(entity.getContent().get(0)).extracting(DataMateKnowledgeEntity::getId, + DataMateKnowledgeEntity::getName, + DataMateKnowledgeEntity::getDescription).containsExactly("1", "test1", "test1知识库"); + assertThat(entity.getContent().get(1)).extracting(DataMateKnowledgeEntity::getId, + DataMateKnowledgeEntity::getName, + DataMateKnowledgeEntity::getDescription).containsExactly("2", "test2", "test2知识库"); + } + + @Test + @DisplayName("查询知识库列表失败,抛出异常") + public void shouldFailWhenListRepoThrowException() { + DataMateKnowledgeListQueryParam param = DataMateKnowledgeListQueryParam.builder().name("error").build(); + assertThatThrownBy(() -> this.manager.listRepos(apiKey, param)).isInstanceOf(KnowledgeException.class) + .extracting("code") + .isEqualTo(130703005); + } + + @Test + @DisplayName("检索知识库成功") + public void shouldOkWhenRetrieve() { + DataMateRetrievalParam param = DataMateRetrievalParam.builder().query("ok").build(); + DataMateRetrievalResult result = this.manager.retrieve(apiKey, param); + assertThat(result.getData().size()).isEqualTo(3); + assertThat(result.getData().get(0).chunkId()).isEqualTo("chunk1"); + assertThat(result.getData().get(0).content()).isEqualTo("content1"); + } + + @Test + @DisplayName("检索知识库失败,抛出异常") + public void shouldFailWhenRetrieveThrowException() { + DataMateRetrievalParam param = DataMateRetrievalParam.builder().query("error").build(); + assertThatThrownBy(() -> this.manager.retrieve(apiKey, param)).isInstanceOf(KnowledgeException.class) + .extracting("code") + .isEqualTo(130703005); + } +} diff --git a/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateKnowledgeBaseInnerController.java b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateKnowledgeBaseInnerController.java new file mode 100644 index 0000000000..ec9a75caf6 --- /dev/null +++ b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateKnowledgeBaseInnerController.java @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved. + * This file is a part of the ModelEngine Project. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +package modelengine.fit.jade.datamate.knowledge; + +import static modelengine.fitframework.util.IoUtils.content; + +import modelengine.fit.http.annotation.PostMapping; +import modelengine.fit.http.annotation.RequestBody; +import modelengine.fit.http.annotation.RequestMapping; +import modelengine.fit.http.client.HttpClientException; +import modelengine.fitframework.annotation.Component; +import modelengine.fitframework.serialization.ObjectSerializer; +import modelengine.fit.jade.datamate.knowledge.entity.DataMateResponse; + +import java.io.IOException; +import java.util.Map; + +/** + * 表示 DataMate 内部接口的打桩实现。 + * + * @author songyongtan + * @since 2026-02-11 + */ +@Component +@RequestMapping(path = "/v2", group = "DataMate知识库内部接口打桩") +public class MockedDataMateKnowledgeBaseInnerController { + private final ObjectSerializer serializer; + + public MockedDataMateKnowledgeBaseInnerController(ObjectSerializer serializer) { + this.serializer = serializer; + } + + @PostMapping(path = "/knowledgeBase") + public Map listRepos(@RequestBody MockedDataMateKnowledgeListQueryParam param) throws IOException { + if (param.getName().equals("error")) { + throw new HttpClientException("error"); + } + String resourceName = "/listRepoResult.json"; + String jsonContent = content(DataMateResponse.class, resourceName); + return serializer.deserialize(jsonContent, Map.class); + } + + @PostMapping(path = "/knowledgebases/query") + public Map retrieve(@RequestBody MockedDataMateRetrievalParam param) throws IOException { + if (param.getQuery().equals("error")) { + throw new HttpClientException("error"); + } + String resourceName = "/retrieveResult.json"; + String jsonContent = content(DataMateResponse.class, resourceName); + return serializer.deserialize(jsonContent, Map.class); + } +} diff --git a/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateKnowledgeListQueryParam.java b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateKnowledgeListQueryParam.java new file mode 100644 index 0000000000..6ef86a3c53 --- /dev/null +++ b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateKnowledgeListQueryParam.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved. + * This file is a part of the ModelEngine Project. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +package modelengine.fit.jade.datamate.knowledge; + +import lombok.Data; +import modelengine.fitframework.serialization.annotation.SerializeStrategy; + +/** + * 表示 {@link modelengine.fit.jade.datamate.knowledge.dto.DataMateKnowledgeListQueryParam} 类的测试类实现。 + * + * @author songyongtan + * @since 2026-02-11 + */ +@Data +@SerializeStrategy(include = SerializeStrategy.Include.NON_NULL) +public class MockedDataMateKnowledgeListQueryParam { + /** + * 页码,从0开始。 + */ + private Integer page; + + /** + * 每页大小。 + */ + private Integer size; + + /** + * 知识库名称过滤。 + */ + private String name; + + /** + * 知识库描述过滤。 + */ + private String description; +} diff --git a/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateRetrievalParam.java b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateRetrievalParam.java new file mode 100644 index 0000000000..ec77c0a6c8 --- /dev/null +++ b/app-builder/plugins/data-mate-knowledge/src/test/java/modelengine/fit/jade/datamate/knowledge/MockedDataMateRetrievalParam.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved. + * This file is a part of the ModelEngine Project. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +package modelengine.fit.jade.datamate.knowledge; + +import lombok.Data; +import modelengine.fitframework.annotation.Property; + +import java.util.List; + +/** + * 表示 {@link modelengine.fit.jade.datamate.knowledge.dto.DataMateRetrievalParam} 类的测试类实现。 + * + * @author songyongtan + * @since 2026-02-11 + */ +@Data +public class MockedDataMateRetrievalParam { + /** + * 检索 query。 + */ + private String query; + /** + * 返回前多少的条目。 + */ + @Property(description = "topK", name = "topK") + private Integer topK; + /** + * 相关性阈值。 + */ + @Property(description = "threshold", name = "threshold") + private Double threshold; + /** + * 指定知识库的id集合。 + */ + @Property(description = "knowledgeBaseIds", name = "knowledgeBaseIds") + private List knowledgeBaseIds; +} diff --git a/app-builder/plugins/data-mate-knowledge/src/test/resources/listRepoResult.json b/app-builder/plugins/data-mate-knowledge/src/test/resources/listRepoResult.json new file mode 100644 index 0000000000..a584b02514 --- /dev/null +++ b/app-builder/plugins/data-mate-knowledge/src/test/resources/listRepoResult.json @@ -0,0 +1,24 @@ +{ + "data": { + "page": 0, + "size": 2, + "totalElements": 2, + "totalPages": 1, + "content": [ + { + "id": "1", + "name": "test1", + "description": "test1知识库", + "createdAt": "2025-04-22T14:27:17Z" + }, + { + "id": "2", + "name": "test2", + "description": "test2知识库", + "createdAt": "2023-10-25T08:06:19Z" + } + ] + }, + "code": "0", + "message": "success" +} diff --git a/app-builder/plugins/data-mate-knowledge/src/test/resources/retrieveResult.json b/app-builder/plugins/data-mate-knowledge/src/test/resources/retrieveResult.json new file mode 100644 index 0000000000..311dea4db8 --- /dev/null +++ b/app-builder/plugins/data-mate-knowledge/src/test/resources/retrieveResult.json @@ -0,0 +1,33 @@ +{ + "data": [ + { + "entity": { + "id": "chunk1", + "text": "content1", + "metadata": "{}" + }, + "score": 0.9, + "primaryKey": "id" + }, + { + "entity": { + "id": "chunk2", + "text": "content2", + "metadata": "{}" + }, + "score": 0.8, + "primaryKey": "id" + }, + { + "entity": { + "id": "chunk3", + "text": "content3", + "metadata": "{}" + }, + "score": 0.7, + "primaryKey": "id" + } + ], + "code": "0", + "message": "success" +} diff --git a/app-builder/plugins/qianfan-knowledge/src/main/java/modelengine/jade/knowledge/external/QianfanKnowledgeBaseManager.java b/app-builder/plugins/qianfan-knowledge/src/main/java/modelengine/jade/knowledge/external/QianfanKnowledgeBaseManager.java index e0fe7a8aa5..12f62ef3a9 100644 --- a/app-builder/plugins/qianfan-knowledge/src/main/java/modelengine/jade/knowledge/external/QianfanKnowledgeBaseManager.java +++ b/app-builder/plugins/qianfan-knowledge/src/main/java/modelengine/jade/knowledge/external/QianfanKnowledgeBaseManager.java @@ -119,8 +119,9 @@ public QianfanRetrievalResult retrieve(String apiKey, QianfanRetrievalParam para private KnowledgeException handleException(HttpClientResponseException ex) { int statusCode = ex.statusCode(); - log.error(this.exceptionMap.get(statusCode).getMsg(), ex); - return new KnowledgeException(this.exceptionMap.get(statusCode), ex.getSimpleMessage()); + KnowledgeManagerRetCode retCode = this.exceptionMap.getOrDefault(statusCode, INTERNAL_SERVICE_ERROR); + log.error(retCode.getMsg(), ex); + return new KnowledgeException(retCode, ex.getSimpleMessage()); } private HttpClassicClient getHttpClient() {