From 48e788d622280c3c7b9d3efc60df93c8f0e73643 Mon Sep 17 00:00:00 2001 From: haopeng Date: Mon, 19 Aug 2024 16:39:30 +0800 Subject: [PATCH] BIGTOP-4189: Mock Data Implementation for AI Chat API (#46) --- .../server/controller/AIChatController.java | 127 ++++++++++++ .../converter/AuthCredentialConverter.java | 38 ++++ .../model/converter/PlatformConverter.java | 33 ++++ .../server/model/dto/AuthCredentialDTO.java | 31 +++ .../manager/server/model/dto/PlatformDTO.java | 29 +++ .../server/model/req/AuthCredentialReq.java | 32 ++++ .../manager/server/model/req/PlatformReq.java | 33 ++++ .../server/model/vo/ChatMessageVO.java | 36 ++++ .../manager/server/model/vo/ChatThreadVO.java | 42 ++++ .../model/vo/PlatformAuthCredentialVO.java | 33 ++++ .../server/model/vo/PlatformAuthorizedVO.java | 36 ++++ .../manager/server/model/vo/PlatformVO.java | 36 ++++ .../manager/server/service/AIChatService.java | 52 +++++ .../service/impl/AIChatServiceImpl.java | 180 ++++++++++++++++++ .../controller/AIChatControllerTest.java | 77 ++++++++ 15 files changed, 815 insertions(+) create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/AIChatController.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/AuthCredentialConverter.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/PlatformConverter.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/AuthCredentialDTO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/PlatformDTO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/AuthCredentialReq.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/PlatformReq.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatMessageVO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatThreadVO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthCredentialVO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthorizedVO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformVO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/AIChatService.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/AIChatServiceImpl.java create mode 100644 bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/AIChatControllerTest.java diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/AIChatController.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/AIChatController.java new file mode 100644 index 00000000..2e3b5610 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/AIChatController.java @@ -0,0 +1,127 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.controller; + +import org.apache.bigtop.manager.server.enums.ResponseStatus; +import org.apache.bigtop.manager.server.model.converter.PlatformConverter; +import org.apache.bigtop.manager.server.model.dto.PlatformDTO; +import org.apache.bigtop.manager.server.model.req.PlatformReq; +import org.apache.bigtop.manager.server.model.vo.ChatMessageVO; +import org.apache.bigtop.manager.server.model.vo.ChatThreadVO; +import org.apache.bigtop.manager.server.model.vo.PlatformAuthCredentialVO; +import org.apache.bigtop.manager.server.model.vo.PlatformAuthorizedVO; +import org.apache.bigtop.manager.server.model.vo.PlatformVO; +import org.apache.bigtop.manager.server.service.AIChatService; +import org.apache.bigtop.manager.server.utils.ResponseEntity; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +import jakarta.annotation.Resource; +import java.util.List; + +@Tag(name = "AI Chat Controller") +@RestController +@RequestMapping("/ai/chat/") +public class AIChatController { + + @Resource + private AIChatService chatService; + + @Operation(summary = "platforms", description = "Get all platforms") + @GetMapping("/platforms") + public ResponseEntity> platforms() { + return ResponseEntity.success(chatService.platforms()); + } + + @Operation(summary = "platforms", description = "Get authorized platforms") + @GetMapping("/platforms/authorized") + public ResponseEntity> authorizedPlatforms() { + return ResponseEntity.success(chatService.authorizedPlatforms()); + } + + @Operation(summary = "platforms", description = "Get authorized platforms") + @GetMapping("/platforms/{platformId}/auth/credential") + public ResponseEntity> platformsAuthCredential(@PathVariable Long platformId) { + return ResponseEntity.success(chatService.platformsAuthCredential(platformId)); + } + + @Operation(summary = "platforms", description = "Add authorized platforms") + @PutMapping("/platforms") + public ResponseEntity addAuthorizedPlatform(@RequestBody PlatformReq platformReq) { + PlatformDTO platformDTO = PlatformConverter.INSTANCE.fromReq2DTO(platformReq); + return ResponseEntity.success(chatService.addAuthorizedPlatform(platformDTO)); + } + + @Operation(summary = "platforms", description = "Delete authorized platforms") + @DeleteMapping("/platforms/{platformId}") + public ResponseEntity deleteAuthorizedPlatform(@PathVariable Long platformId) { + int code = chatService.deleteAuthorizedPlatform(platformId); + if (code != 0) { + return ResponseEntity.error(ResponseStatus.PARAMETER_ERROR, "Permission denied"); + } + return ResponseEntity.success(true); + } + + @Operation(summary = "new threads", description = "Create a chat threads") + @PutMapping("/platforms/{platformId}/threads") + public ResponseEntity createChatThreads(@PathVariable Long platformId, @RequestParam String model) { + return ResponseEntity.success(chatService.createChatThreads(platformId, model)); + } + + @Operation(summary = "delete threads", description = "Delete a chat threads") + @DeleteMapping("platforms/{platformId}/threads/{threadId}") + public ResponseEntity deleteChatThreads(@PathVariable Long platformId, @PathVariable Long threadId) { + int code = chatService.deleteChatThreads(platformId, threadId); + if (code != 0) { + return ResponseEntity.error(ResponseStatus.PARAMETER_ERROR, "No Content"); + } + return ResponseEntity.success(true); + } + + @Operation(summary = "get", description = "Get all threads of a platform") + @GetMapping("platforms/{platformId}/threads") + public ResponseEntity> getAllChatThreads( + @PathVariable Long platformId, @RequestParam String model) { + return ResponseEntity.success(chatService.getAllChatThreads(platformId, model)); + } + + @Operation(summary = "talk", description = "Talk with AI") + @PostMapping("platforms/{platformId}/threads/{threadId}/talk") + public SseEmitter talk(@PathVariable Long platformId, @PathVariable Long threadId, @RequestParam String message) { + return chatService.talk(platformId, threadId, message); + } + + @Operation(summary = "history", description = "Get chat records") + @GetMapping("platforms/{platformId}/threads/{threadId}/history") + public ResponseEntity> history(@PathVariable Long platformId, @PathVariable Long threadId) { + return ResponseEntity.success(chatService.history(platformId, threadId)); + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/AuthCredentialConverter.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/AuthCredentialConverter.java new file mode 100644 index 00000000..937bae56 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/AuthCredentialConverter.java @@ -0,0 +1,38 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.converter; + +import org.apache.bigtop.manager.server.config.MapStructSharedConfig; +import org.apache.bigtop.manager.server.model.dto.PropertyDTO; +import org.apache.bigtop.manager.server.model.vo.PropertyVO; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper(config = MapStructSharedConfig.class) +public interface AuthCredentialConverter { + + AuthCredentialConverter INSTANCE = Mappers.getMapper(AuthCredentialConverter.class); + + PropertyVO fromDTO2VO(PropertyDTO propertyDTO); + + List fromDTO2VO(List propertyDTOList); +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/PlatformConverter.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/PlatformConverter.java new file mode 100644 index 00000000..aa4c3432 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/PlatformConverter.java @@ -0,0 +1,33 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.converter; + +import org.apache.bigtop.manager.server.config.MapStructSharedConfig; +import org.apache.bigtop.manager.server.model.dto.PlatformDTO; +import org.apache.bigtop.manager.server.model.req.PlatformReq; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper(config = MapStructSharedConfig.class) +public interface PlatformConverter { + PlatformConverter INSTANCE = Mappers.getMapper(PlatformConverter.class); + + PlatformDTO fromReq2DTO(PlatformReq platformReq); +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/AuthCredentialDTO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/AuthCredentialDTO.java new file mode 100644 index 00000000..ec6f5059 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/AuthCredentialDTO.java @@ -0,0 +1,31 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.dto; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class AuthCredentialDTO implements Serializable { + + private String key; + + private String value; +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/PlatformDTO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/PlatformDTO.java new file mode 100644 index 00000000..f26245f5 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/PlatformDTO.java @@ -0,0 +1,29 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class PlatformDTO { + private Long platformId; + private List authCredentials; +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/AuthCredentialReq.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/AuthCredentialReq.java new file mode 100644 index 00000000..e368a4d1 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/AuthCredentialReq.java @@ -0,0 +1,32 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.req; + +import lombok.Data; + +import jakarta.validation.constraints.NotBlank; + +@Data +public class AuthCredentialReq { + + @NotBlank + private String key; + + private String value; +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/PlatformReq.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/PlatformReq.java new file mode 100644 index 00000000..d15abfce --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/req/PlatformReq.java @@ -0,0 +1,33 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.req; + +import lombok.Data; + +import jakarta.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class PlatformReq { + @NotEmpty + private Long platformId; + + @NotEmpty + private List authCredentials; +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatMessageVO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatMessageVO.java new file mode 100644 index 00000000..981529bd --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatMessageVO.java @@ -0,0 +1,36 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.vo; + +import lombok.Data; + +@Data +public class ChatMessageVO { + private String sender; + + private String message; + + private String createTime; + + public ChatMessageVO(String sender, String messageText, String createTime) { + this.sender = sender; + this.message = messageText; + this.createTime = createTime; + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatThreadVO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatThreadVO.java new file mode 100644 index 00000000..2349fdbd --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ChatThreadVO.java @@ -0,0 +1,42 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.vo; + +import lombok.Data; + +@Data +public class ChatThreadVO { + private Long threadId; + + private Long platformId; + + private String model; + + private String createTime; + + private String updateTime; + + public ChatThreadVO(Long threadId, Long platformId, String model, String createTime) { + this.threadId = threadId; + this.platformId = platformId; + this.model = model; + this.createTime = createTime; + this.updateTime = createTime; + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthCredentialVO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthCredentialVO.java new file mode 100644 index 00000000..edfe0ff3 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthCredentialVO.java @@ -0,0 +1,33 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.vo; + +import lombok.Data; + +@Data +public class PlatformAuthCredentialVO { + private String name; + + private String displayName; + + public PlatformAuthCredentialVO(String name, String displayName) { + this.name = name; + this.displayName = name; + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthorizedVO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthorizedVO.java new file mode 100644 index 00000000..e957f7aa --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformAuthorizedVO.java @@ -0,0 +1,36 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.vo; + +import lombok.Data; + +@Data +public class PlatformAuthorizedVO { + private Long platformId; + + private String platformName; + + private String supportModels; + + public PlatformAuthorizedVO(long platformId, String name, String models) { + this.platformId = platformId; + this.platformName = name; + this.supportModels = models; + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformVO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformVO.java new file mode 100644 index 00000000..5e127229 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/PlatformVO.java @@ -0,0 +1,36 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.model.vo; + +import lombok.Data; + +@Data +public class PlatformVO { + private Long id; + + private String name; + + private String supportModels; + + public PlatformVO(Long id, String name, String models) { + this.id = id; + this.name = name; + this.supportModels = models; + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/AIChatService.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/AIChatService.java new file mode 100644 index 00000000..d3cf1255 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/AIChatService.java @@ -0,0 +1,52 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.service; + +import org.apache.bigtop.manager.server.model.dto.PlatformDTO; +import org.apache.bigtop.manager.server.model.vo.ChatMessageVO; +import org.apache.bigtop.manager.server.model.vo.ChatThreadVO; +import org.apache.bigtop.manager.server.model.vo.PlatformAuthCredentialVO; +import org.apache.bigtop.manager.server.model.vo.PlatformAuthorizedVO; +import org.apache.bigtop.manager.server.model.vo.PlatformVO; + +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.List; + +public interface AIChatService { + List platforms(); + + List authorizedPlatforms(); + + PlatformVO addAuthorizedPlatform(PlatformDTO platformDTO); + + List platformsAuthCredential(Long platformId); + + int deleteAuthorizedPlatform(Long platformId); + + ChatThreadVO createChatThreads(Long platformId, String model); + + int deleteChatThreads(Long platformId, Long threadId); + + List getAllChatThreads(Long platformId, String model); + + SseEmitter talk(Long platformId, Long threadId, String message); + + List history(Long platformId, Long threadId); +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/AIChatServiceImpl.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/AIChatServiceImpl.java new file mode 100644 index 00000000..6dca1bca --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/AIChatServiceImpl.java @@ -0,0 +1,180 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.service.impl; + +import org.apache.bigtop.manager.common.utils.DateUtils; +import org.apache.bigtop.manager.server.model.dto.PlatformDTO; +import org.apache.bigtop.manager.server.model.vo.ChatMessageVO; +import org.apache.bigtop.manager.server.model.vo.ChatThreadVO; +import org.apache.bigtop.manager.server.model.vo.PlatformAuthCredentialVO; +import org.apache.bigtop.manager.server.model.vo.PlatformAuthorizedVO; +import org.apache.bigtop.manager.server.model.vo.PlatformVO; +import org.apache.bigtop.manager.server.service.AIChatService; + +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Random; + +@Slf4j +@Service +public class AIChatServiceImpl implements AIChatService { + @Override + public List platforms() { + List platforms = new ArrayList<>(); + platforms.add(new PlatformVO(1L, "OpenAI", "GPT-3.5,GPT-4o")); + platforms.add(new PlatformVO(2L, "ChatGLM", "GPT-3.5,GPT-4o")); + return platforms; + } + + @Override + public List authorizedPlatforms() { + List authorizedPlatforms = new ArrayList<>(); + authorizedPlatforms.add(new PlatformAuthorizedVO(1L, "OpenAI", "GPT-3.5,GPT-4o")); + authorizedPlatforms.add(new PlatformAuthorizedVO(2L, "ChatGLM", "GPT-4o")); + return authorizedPlatforms; + } + + @Override + public PlatformVO addAuthorizedPlatform(PlatformDTO platformDTO) { + log.info("Adding authorized platform: {}", platformDTO); + log.info(platformDTO.getAuthCredentials().toString()); + return new PlatformVO(1L, "OpenAI", "GPT-3.5,GPT-4o"); + } + + @Override + public List platformsAuthCredential(Long platformId) { + List platformAuthCredentials = new ArrayList<>(); + platformAuthCredentials.add(new PlatformAuthCredentialVO("api-key", "API Key")); + platformAuthCredentials.add(new PlatformAuthCredentialVO("api-secret", "API Secret")); + return platformAuthCredentials; + } + + @Override + public int deleteAuthorizedPlatform(Long platformId) { + Random random = new Random(); + int randomInt = random.nextInt(); + return randomInt % 2; + } + + @Override + public ChatThreadVO createChatThreads(Long platformId, String model) { + + return new ChatThreadVO(1L, platformId, model, DateUtils.format(new Date())); + } + + @Override + public int deleteChatThreads(Long platformId, Long threadId) { + Random random = new Random(); + int randomInt = random.nextInt(); + return randomInt % 2; + } + + @Override + public List getAllChatThreads(Long platformId, String model) { + List chatThreads = new ArrayList<>(); + if (model.equals("GPT-3.5")) { + ChatThreadVO chatThreadVO = new ChatThreadVO(1L, platformId, "GPT-3.5", DateUtils.format(new Date())); + chatThreads.add(chatThreadVO); + ChatThreadVO chatThreadVO2 = new ChatThreadVO(3L, platformId, "GPT-3.5", DateUtils.format(new Date())); + chatThreads.add(chatThreadVO2); + } + if (model.equals("GPT-4o")) { + ChatThreadVO chatThreadVO = new ChatThreadVO(2L, platformId, "GPT-4o", DateUtils.format(new Date())); + chatThreads.add(chatThreadVO); + } + return chatThreads; + } + + @Override + public SseEmitter talk(Long platformId, Long threadId, String message) { + String fullMessage = "Don't ask me" + message; + fullMessage += + """ + I won't tell you Bigtop Manager provides a modern, low-threshold web application to simplify \ + the deployment and management of components for Bigtop, similar to Apache Ambari and Cloudera \ + Manager. + And Bigtop Manager provides a modern, low-threshold web application to simplify \ + the deployment and management of components for Bigtop, similar to Apache Ambari and Cloudera \ + Manager. + """; + + SseEmitter emitter = new SseEmitter(); + Random random = new Random(); + + try { + StringBuilder remainingMessage = new StringBuilder(fullMessage); + + while (!remainingMessage.isEmpty()) { + int charsToSend = random.nextInt(21); + // 2% probability of simulated transmission failure + if (random.nextInt(50) == 2) { + try { + emitter.send(SseEmitter.event().name("error").data("broken pipe")); + } catch (IOException e) { + emitter.completeWithError(e); + } + emitter.complete(); + return emitter; + } + charsToSend = Math.min(charsToSend, remainingMessage.length()); + + String part = remainingMessage.substring(0, charsToSend); + remainingMessage.delete(0, charsToSend); + + emitter.send(SseEmitter.event().name("message").data(part)); + + int delay = random.nextInt(101); + Thread.sleep(delay); + } + } catch (IOException | InterruptedException e) { + emitter.completeWithError(e); + throw new RuntimeException(e); + } + + emitter.complete(); + return emitter; + } + + @Override + public List history(Long platformId, Long threadId) { + List chatMessages = new ArrayList<>(); + Random random = new Random(); + int numberOfMessages = random.nextInt(11); + boolean isUser = true; + + for (int i = 0; i < numberOfMessages; i++) { + String sender = isUser ? "user" : "AI"; + String messageText = isUser ? "hello" : "hello, I'm GPT"; + messageText += i; + + ChatMessageVO message = new ChatMessageVO(sender, messageText, DateUtils.format(new Date())); + chatMessages.add(message); + + isUser = !isUser; + } + return chatMessages; + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/AIChatControllerTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/AIChatControllerTest.java new file mode 100644 index 00000000..e271b6da --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/AIChatControllerTest.java @@ -0,0 +1,77 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.controller; + +import org.apache.bigtop.manager.server.model.vo.PlatformVO; +import org.apache.bigtop.manager.server.service.AIChatService; +import org.apache.bigtop.manager.server.utils.MessageSourceUtils; +import org.apache.bigtop.manager.server.utils.ResponseEntity; + +import org.junit.jupiter.api.AfterEach; +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.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class AIChatControllerTest { + + @Mock + private AIChatService chatService; + + @InjectMocks + private AIChatController chatController; + + private MockedStatic mockedMessageSourceUtils; + + @BeforeEach + void setUp() { + mockedMessageSourceUtils = Mockito.mockStatic(MessageSourceUtils.class); + when(MessageSourceUtils.getMessage(any())).thenReturn("Mocked message"); + } + + @AfterEach + void tearDown() { + mockedMessageSourceUtils.close(); + } + + @Test + void getAllPlatforms() { + + List platforms = new ArrayList<>(); + when(chatService.platforms()).thenReturn(platforms); + + ResponseEntity> response = chatController.platforms(); + + assertEquals(platforms, response.getData()); + } + + // TODO +}