This is an automated email from the ASF dual-hosted git repository.

liuhaopeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git


The following commit(s) were added to refs/heads/main by this push:
     new 3fc28122 BIGTOP-4372: Adjust APIs related to cluster management for UI 
needs (#180)
3fc28122 is described below

commit 3fc28122be6c6971b600bfc51d248db8a1b2747e
Author: Zhiguo Wu <[email protected]>
AuthorDate: Wed Feb 19 21:49:00 2025 +0800

    BIGTOP-4372: Adjust APIs related to cluster management for UI needs (#180)
---
 .../agent/grpc/interceptor/TaskInterceptor.java    |  2 +-
 .../grpc/interceptor/TaskInterceptorTest.java      | 16 +++----
 .../command/validator/ClusterRestartValidator.java | 56 ++++++++++++++++++++++
 .../command/validator/ClusterStartValidator.java   | 56 ++++++++++++++++++++++
 .../command/validator/ClusterStopValidator.java    | 56 ++++++++++++++++++++++
 .../server/controller/ServiceController.java       | 17 +++++++
 .../manager/server/controller/StackController.java |  9 ++--
 .../manager/server/enums/ApiExceptionEnum.java     |  1 +
 .../bigtop/manager/server/enums/LocaleKeys.java    |  1 +
 .../bigtop/manager/server/model/vo/JobVO.java      |  2 +
 .../model/vo/{JobVO.java => ServiceClusterVO.java} | 18 +++----
 .../model/vo/{JobVO.java => ServiceUserVO.java}    | 16 ++-----
 .../manager/server/service/ServiceService.java     |  8 ++++
 .../manager/server/service/StackService.java       |  7 ++-
 .../server/service/impl/JobServiceImpl.java        | 19 +++++++-
 .../server/service/impl/ServiceServiceImpl.java    | 33 +++++++++++++
 .../server/service/impl/StackServiceImpl.java      | 40 +++++++++++-----
 .../main/resources/i18n/messages_en_US.properties  |  1 +
 .../main/resources/i18n/messages_zh_CN.properties  |  1 +
 19 files changed, 305 insertions(+), 54 deletions(-)

diff --git 
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
 
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
index c2550509..43f382ed 100644
--- 
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
+++ 
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptor.java
@@ -107,7 +107,7 @@ public class TaskInterceptor implements ServerInterceptor {
 
         // Every task will have taskId, but TaskLogRequest have it also, so we 
need to exclude it
         Class<?> clazz = obj.getClass();
-        if (clazz.isInstance(TaskLogRequest.class)) {
+        if (TaskLogRequest.class.isAssignableFrom(clazz)) {
             return false;
         }
 
diff --git 
a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptorTest.java
 
b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptorTest.java
index f9425578..7b53c485 100644
--- 
a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptorTest.java
+++ 
b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/grpc/interceptor/TaskInterceptorTest.java
@@ -19,6 +19,7 @@
 package org.apache.bigtop.manager.agent.grpc.interceptor;
 
 import org.apache.bigtop.manager.common.utils.ProjectPathUtils;
+import org.apache.bigtop.manager.grpc.generated.TaskLogRequest;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -91,16 +92,17 @@ public class TaskInterceptorTest {
     }
 
     @Test
-    public void testIsTaskRequestTaskRequest() {
-        TaskLogRequest taskLogRequest = new TaskLogRequest();
+    public void testIsTaskLogRequestTaskRequest() {
+        TaskLogRequest taskLogRequest =
+                TaskLogRequest.newBuilder().setTaskId(1L).build();
 
         Boolean result = taskInterceptor.isTaskRequest(taskLogRequest);
 
-        assertTrue(result);
+        assertFalse(result);
     }
 
     @Test
-    public void testIsTaskRequestTaskWithGetTaskIdMethod() {
+    public void testIsTaskRequestTaskRequest() {
         Task task = new Task();
 
         Boolean result = taskInterceptor.isTaskRequest(task);
@@ -129,10 +131,4 @@ public class TaskInterceptorTest {
             return 1L;
         }
     }
-
-    private static class TaskLogRequest {
-        public Long getTaskId() {
-            return 1L;
-        }
-    }
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterRestartValidator.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterRestartValidator.java
new file mode 100644
index 00000000..3a399f8b
--- /dev/null
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterRestartValidator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.command.validator;
+
+import org.apache.bigtop.manager.common.enums.Command;
+import org.apache.bigtop.manager.dao.po.ServicePO;
+import org.apache.bigtop.manager.dao.repository.ServiceDao;
+import org.apache.bigtop.manager.server.command.CommandIdentifier;
+import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
+import org.apache.bigtop.manager.server.enums.CommandLevel;
+import org.apache.bigtop.manager.server.exception.ApiException;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import org.springframework.stereotype.Component;
+
+import jakarta.annotation.Resource;
+import java.util.List;
+
+@Component
+public class ClusterRestartValidator implements CommandValidator {
+
+    @Resource
+    private ServiceDao serviceDao;
+
+    @Override
+    public List<CommandIdentifier> getCommandIdentifiers() {
+        return List.of(new CommandIdentifier(CommandLevel.CLUSTER, 
Command.RESTART));
+    }
+
+    @Override
+    public void validate(ValidatorContext context) {
+        Long clusterId = context.getCommandDTO().getClusterId();
+        List<ServicePO> servicePOList = serviceDao.findByClusterId(clusterId);
+
+        if (CollectionUtils.isEmpty(servicePOList)) {
+            throw new ApiException(ApiExceptionEnum.CLUSTER_HAS_NO_SERVICES);
+        }
+    }
+}
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
new file mode 100644
index 00000000..e8677430
--- /dev/null
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.command.validator;
+
+import org.apache.bigtop.manager.common.enums.Command;
+import org.apache.bigtop.manager.dao.po.ServicePO;
+import org.apache.bigtop.manager.dao.repository.ServiceDao;
+import org.apache.bigtop.manager.server.command.CommandIdentifier;
+import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
+import org.apache.bigtop.manager.server.enums.CommandLevel;
+import org.apache.bigtop.manager.server.exception.ApiException;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import org.springframework.stereotype.Component;
+
+import jakarta.annotation.Resource;
+import java.util.List;
+
+@Component
+public class ClusterStartValidator implements CommandValidator {
+
+    @Resource
+    private ServiceDao serviceDao;
+
+    @Override
+    public List<CommandIdentifier> getCommandIdentifiers() {
+        return List.of(new CommandIdentifier(CommandLevel.CLUSTER, 
Command.START));
+    }
+
+    @Override
+    public void validate(ValidatorContext context) {
+        Long clusterId = context.getCommandDTO().getClusterId();
+        List<ServicePO> servicePOList = serviceDao.findByClusterId(clusterId);
+
+        if (CollectionUtils.isEmpty(servicePOList)) {
+            throw new ApiException(ApiExceptionEnum.CLUSTER_HAS_NO_SERVICES);
+        }
+    }
+}
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStopValidator.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStopValidator.java
new file mode 100644
index 00000000..d4d6e999
--- /dev/null
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStopValidator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.command.validator;
+
+import org.apache.bigtop.manager.common.enums.Command;
+import org.apache.bigtop.manager.dao.po.ServicePO;
+import org.apache.bigtop.manager.dao.repository.ServiceDao;
+import org.apache.bigtop.manager.server.command.CommandIdentifier;
+import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
+import org.apache.bigtop.manager.server.enums.CommandLevel;
+import org.apache.bigtop.manager.server.exception.ApiException;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import org.springframework.stereotype.Component;
+
+import jakarta.annotation.Resource;
+import java.util.List;
+
+@Component
+public class ClusterStopValidator implements CommandValidator {
+
+    @Resource
+    private ServiceDao serviceDao;
+
+    @Override
+    public List<CommandIdentifier> getCommandIdentifiers() {
+        return List.of(new CommandIdentifier(CommandLevel.CLUSTER, 
Command.STOP));
+    }
+
+    @Override
+    public void validate(ValidatorContext context) {
+        Long clusterId = context.getCommandDTO().getClusterId();
+        List<ServicePO> servicePOList = serviceDao.findByClusterId(clusterId);
+
+        if (CollectionUtils.isEmpty(servicePOList)) {
+            throw new ApiException(ApiExceptionEnum.CLUSTER_HAS_NO_SERVICES);
+        }
+    }
+}
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ServiceController.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ServiceController.java
index a52f1c32..0af7912b 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ServiceController.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ServiceController.java
@@ -24,6 +24,7 @@ import 
org.apache.bigtop.manager.server.model.req.ServiceConfigSnapshotReq;
 import org.apache.bigtop.manager.server.model.vo.PageVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceConfigSnapshotVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
+import org.apache.bigtop.manager.server.model.vo.ServiceUserVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceVO;
 import org.apache.bigtop.manager.server.service.ServiceService;
 import org.apache.bigtop.manager.server.utils.ResponseEntity;
@@ -72,6 +73,22 @@ public class ServiceController {
         return ResponseEntity.success(serviceService.list(query));
     }
 
+    @Parameters({
+        @Parameter(in = ParameterIn.QUERY, name = "pageNum", schema = 
@Schema(type = "integer", defaultValue = "1")),
+        @Parameter(in = ParameterIn.QUERY, name = "pageSize", schema = 
@Schema(type = "integer", defaultValue = "10")),
+        @Parameter(in = ParameterIn.QUERY, name = "orderBy", schema = 
@Schema(type = "string", defaultValue = "id")),
+        @Parameter(
+                in = ParameterIn.QUERY,
+                name = "sort",
+                description = "asc/desc",
+                schema = @Schema(type = "string", defaultValue = "asc"))
+    })
+    @Operation(summary = "service user list", description = "List service 
users")
+    @GetMapping("/users")
+    public ResponseEntity<PageVO<ServiceUserVO>> serviceUsers(@PathVariable 
Long clusterId) {
+        return ResponseEntity.success(serviceService.serviceUsers(clusterId));
+    }
+
     @Operation(summary = "get", description = "Get a service")
     @GetMapping("/{id}")
     public ResponseEntity<ServiceVO> get(@PathVariable Long clusterId, 
@PathVariable Long id) {
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/StackController.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/StackController.java
index 0df4f53d..b2fe0a67 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/StackController.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/StackController.java
@@ -18,13 +18,12 @@
  */
 package org.apache.bigtop.manager.server.controller;
 
-import org.apache.bigtop.manager.server.model.vo.ClusterVO;
+import org.apache.bigtop.manager.server.model.vo.ServiceClusterVO;
 import org.apache.bigtop.manager.server.model.vo.StackVO;
 import org.apache.bigtop.manager.server.service.StackService;
 import org.apache.bigtop.manager.server.utils.ResponseEntity;
 
 import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -49,8 +48,8 @@ public class StackController {
     }
 
     @Operation(summary = "service clusters", description = "Get service 
clusters")
-    @GetMapping("/services/{serviceName}/clusters")
-    public ResponseEntity<List<ClusterVO>> serviceClusters(@PathVariable 
String serviceName) {
-        return 
ResponseEntity.success(stackService.serviceClusters(serviceName));
+    @GetMapping("/services/clusters")
+    public ResponseEntity<List<ServiceClusterVO>> serviceClusters() {
+        return ResponseEntity.success(stackService.serviceClusters());
     }
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
index 16191a1c..429fe597 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
@@ -35,6 +35,7 @@ public enum ApiExceptionEnum {
     CLUSTER_EXISTS(11001, LocaleKeys.CLUSTER_EXISTS),
     CLUSTER_HAS_HOSTS(11002, LocaleKeys.CLUSTER_HAS_HOSTS),
     CLUSTER_HAS_SERVICES(11003, LocaleKeys.CLUSTER_HAS_SERVICES),
+    CLUSTER_HAS_NO_SERVICES(11004, LocaleKeys.CLUSTER_HAS_NO_SERVICES),
 
     // Host Exceptions -- 12000 ~ 12999
     HOST_NOT_FOUND(12000, LocaleKeys.HOST_NOT_FOUND),
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
index e9762433..c2fd671c 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
@@ -38,6 +38,7 @@ public enum LocaleKeys {
     CLUSTER_EXISTS("cluster.exists"),
     CLUSTER_HAS_HOSTS("cluster.has.hosts"),
     CLUSTER_HAS_SERVICES("cluster.has.services"),
+    CLUSTER_HAS_NO_SERVICES("cluster.has.no.services"),
 
     HOST_NOT_FOUND("host.not.found"),
     HOST_ASSIGNED("host.assigned"),
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
index ef554a1e..dbc9af5e 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
@@ -35,5 +35,7 @@ public class JobVO {
 
     private String updateTime;
 
+    private Integer progress;
+
     private List<StageVO> stages;
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceClusterVO.java
similarity index 81%
copy from 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
copy to 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceClusterVO.java
index ef554a1e..a8d9fe87 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceClusterVO.java
@@ -18,22 +18,18 @@
  */
 package org.apache.bigtop.manager.server.model.vo;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.List;
 
 @Data
-public class JobVO {
+@NoArgsConstructor
+@AllArgsConstructor
+public class ServiceClusterVO {
 
-    private Long id;
+    private String serviceName;
 
-    private String state;
-
-    private String name;
-
-    private String createTime;
-
-    private String updateTime;
-
-    private List<StageVO> stages;
+    private List<ClusterVO> clusters;
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceUserVO.java
similarity index 80%
copy from 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
copy to 
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceUserVO.java
index ef554a1e..45c5a343 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/JobVO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceUserVO.java
@@ -20,20 +20,14 @@ package org.apache.bigtop.manager.server.model.vo;
 
 import lombok.Data;
 
-import java.util.List;
-
 @Data
-public class JobVO {
-
-    private Long id;
-
-    private String state;
+public class ServiceUserVO {
 
-    private String name;
+    private String displayName;
 
-    private String createTime;
+    private String user;
 
-    private String updateTime;
+    private String userGroup;
 
-    private List<StageVO> stages;
+    private String desc;
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/ServiceService.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/ServiceService.java
index 73679574..dfbfda62 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/ServiceService.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/ServiceService.java
@@ -24,6 +24,7 @@ import 
org.apache.bigtop.manager.server.model.req.ServiceConfigSnapshotReq;
 import org.apache.bigtop.manager.server.model.vo.PageVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceConfigSnapshotVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
+import org.apache.bigtop.manager.server.model.vo.ServiceUserVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceVO;
 
 import java.util.List;
@@ -37,6 +38,13 @@ public interface ServiceService {
      */
     PageVO<ServiceVO> list(ServiceQuery query);
 
+    /**
+     * Get service users.
+     *
+     * @return service users
+     */
+    PageVO<ServiceUserVO> serviceUsers(Long clusterId);
+
     /**
      * Get a service.
      *
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/StackService.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/StackService.java
index bf104078..1e31bcf3 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/StackService.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/StackService.java
@@ -18,7 +18,7 @@
  */
 package org.apache.bigtop.manager.server.service;
 
-import org.apache.bigtop.manager.server.model.vo.ClusterVO;
+import org.apache.bigtop.manager.server.model.vo.ServiceClusterVO;
 import org.apache.bigtop.manager.server.model.vo.StackVO;
 
 import java.util.List;
@@ -35,8 +35,7 @@ public interface StackService {
     /**
      * Get service clusters.
      *
-     * @param serviceName Service name
-     * @return Clusters
+     * @return Service clusters
      */
-    List<ClusterVO> serviceClusters(String serviceName);
+    List<ServiceClusterVO> serviceClusters();
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
index fa3a6999..2a208f97 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
@@ -54,6 +54,8 @@ import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 
 import jakarta.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -78,8 +80,23 @@ public class JobServiceImpl implements JobService {
         try (Page<?> ignored =
                 PageHelper.startPage(pageQuery.getPageNum(), 
pageQuery.getPageSize(), pageQuery.getOrderBy())) {
             List<JobPO> jobPOList = jobDao.findByClusterId(clusterId);
+            List<JobVO> jobVOList = new ArrayList<>();
+            for (JobPO jobPO : jobPOList) {
+                List<StagePO> stagePOList = 
stageDao.findByJobId(jobPO.getId());
+                List<StagePO> runningStagePOList = stagePOList.stream()
+                        .filter(stagePO -> List.of(JobState.PROCESSING, 
JobState.SUCCESSFUL)
+                                
.contains(JobState.fromString(stagePO.getState())))
+                        .toList();
+                JobVO jobVO = JobConverter.INSTANCE.fromPO2VO(jobPO);
+                jobVO.setProgress(new BigDecimal(runningStagePOList.size())
+                        .divide(new BigDecimal(stagePOList.size()), 2, 
RoundingMode.HALF_UP)
+                        .multiply(new BigDecimal(100))
+                        .intValue());
+                jobVOList.add(jobVO);
+            }
+
             PageInfo<JobPO> pageInfo = new PageInfo<>(jobPOList);
-            return PageVO.of(pageInfo);
+            return PageVO.of(jobVOList, pageInfo.getTotal());
         } finally {
             PageHelper.clearPage();
         }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ServiceServiceImpl.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ServiceServiceImpl.java
index 9c99ddbf..af9c0a87 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ServiceServiceImpl.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ServiceServiceImpl.java
@@ -19,12 +19,14 @@
 package org.apache.bigtop.manager.server.service.impl;
 
 import org.apache.bigtop.manager.common.utils.JsonUtils;
+import org.apache.bigtop.manager.dao.po.ClusterPO;
 import org.apache.bigtop.manager.dao.po.ComponentPO;
 import org.apache.bigtop.manager.dao.po.ServiceConfigPO;
 import org.apache.bigtop.manager.dao.po.ServiceConfigSnapshotPO;
 import org.apache.bigtop.manager.dao.po.ServicePO;
 import org.apache.bigtop.manager.dao.query.ComponentQuery;
 import org.apache.bigtop.manager.dao.query.ServiceQuery;
+import org.apache.bigtop.manager.dao.repository.ClusterDao;
 import org.apache.bigtop.manager.dao.repository.ComponentDao;
 import org.apache.bigtop.manager.dao.repository.ServiceConfigDao;
 import org.apache.bigtop.manager.dao.repository.ServiceConfigSnapshotDao;
@@ -41,6 +43,7 @@ import 
org.apache.bigtop.manager.server.model.req.ServiceConfigSnapshotReq;
 import org.apache.bigtop.manager.server.model.vo.PageVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceConfigSnapshotVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
+import org.apache.bigtop.manager.server.model.vo.ServiceUserVO;
 import org.apache.bigtop.manager.server.model.vo.ServiceVO;
 import org.apache.bigtop.manager.server.service.ServiceService;
 import org.apache.bigtop.manager.server.utils.PageUtils;
@@ -57,6 +60,7 @@ import com.github.pagehelper.PageInfo;
 import lombok.extern.slf4j.Slf4j;
 
 import jakarta.annotation.Resource;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -65,6 +69,9 @@ import java.util.Map;
 @Service
 public class ServiceServiceImpl implements ServiceService {
 
+    @Resource
+    private ClusterDao clusterDao;
+
     @Resource
     private ServiceDao serviceDao;
 
@@ -90,6 +97,32 @@ public class ServiceServiceImpl implements ServiceService {
         }
     }
 
+    @Override
+    public PageVO<ServiceUserVO> serviceUsers(Long clusterId) {
+        PageQuery pageQuery = PageUtils.getPageQuery();
+        try (Page<?> ignored =
+                PageHelper.startPage(pageQuery.getPageNum(), 
pageQuery.getPageSize(), pageQuery.getOrderBy())) {
+            ServiceQuery query = 
ServiceQuery.builder().clusterId(clusterId).build();
+            List<ServicePO> servicePOList = serviceDao.findByQuery(query);
+
+            ClusterPO clusterPO = clusterDao.findById(clusterId);
+            List<ServiceUserVO> res = new ArrayList<>();
+            for (ServicePO servicePO : servicePOList) {
+                ServiceUserVO serviceUserVO = new ServiceUserVO();
+                serviceUserVO.setDisplayName(servicePO.getDisplayName());
+                serviceUserVO.setUser(servicePO.getUser());
+                serviceUserVO.setUserGroup(clusterPO.getUserGroup());
+                serviceUserVO.setDesc(servicePO.getDesc());
+                res.add(serviceUserVO);
+            }
+
+            PageInfo<ServicePO> pageInfo = new PageInfo<>(servicePOList);
+            return PageVO.of(res, pageInfo.getTotal());
+        } finally {
+            PageHelper.clearPage();
+        }
+    }
+
     @Override
     public ServiceVO get(Long id) {
         return ServiceConverter.INSTANCE.fromPO2VO(serviceDao.findById(id));
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/StackServiceImpl.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/StackServiceImpl.java
index 08517a52..472a78e8 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/StackServiceImpl.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/StackServiceImpl.java
@@ -18,9 +18,7 @@
  */
 package org.apache.bigtop.manager.server.service.impl;
 
-import org.apache.bigtop.manager.dao.po.ClusterPO;
 import org.apache.bigtop.manager.dao.po.ServicePO;
-import org.apache.bigtop.manager.dao.query.ServiceQuery;
 import org.apache.bigtop.manager.dao.repository.ClusterDao;
 import org.apache.bigtop.manager.dao.repository.ServiceDao;
 import org.apache.bigtop.manager.server.model.converter.ClusterConverter;
@@ -29,10 +27,13 @@ import 
org.apache.bigtop.manager.server.model.converter.StackConverter;
 import org.apache.bigtop.manager.server.model.dto.ServiceDTO;
 import org.apache.bigtop.manager.server.model.dto.StackDTO;
 import org.apache.bigtop.manager.server.model.vo.ClusterVO;
+import org.apache.bigtop.manager.server.model.vo.ServiceClusterVO;
 import org.apache.bigtop.manager.server.model.vo.StackVO;
 import org.apache.bigtop.manager.server.service.StackService;
 import org.apache.bigtop.manager.server.utils.StackUtils;
 
+import org.apache.commons.collections4.CollectionUtils;
+
 import org.springframework.stereotype.Service;
 
 import lombok.extern.slf4j.Slf4j;
@@ -41,6 +42,8 @@ import jakarta.annotation.Resource;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -72,16 +75,31 @@ public class StackServiceImpl implements StackService {
     }
 
     @Override
-    public List<ClusterVO> serviceClusters(String serviceName) {
-        ServiceQuery query = ServiceQuery.builder().name(serviceName).build();
-        List<ServicePO> servicePOList = serviceDao.findByQuery(query);
-        if (servicePOList.isEmpty()) {
-            return new ArrayList<>();
+    public List<ServiceClusterVO> serviceClusters() {
+        List<ServiceClusterVO> res = new ArrayList<>();
+        // ID - ClusterVO map
+        Map<Long, ClusterVO> clusterVOMap = 
ClusterConverter.INSTANCE.fromPO2VO(clusterDao.findAll()).stream()
+                .collect(Collectors.toMap(ClusterVO::getId, 
Function.identity()));
+        // Name - ServicePO map
+        Map<String, List<ServicePO>> servicePONameMap =
+                
serviceDao.findAll().stream().collect(Collectors.groupingBy(ServicePO::getName));
+        List<ServiceDTO> serviceDTOList = StackUtils.getAllStacks().stream()
+                .map(StackUtils::getServiceDTOList)
+                .flatMap(List::stream)
+                .toList();
+        for (ServiceDTO serviceDTO : serviceDTOList) {
+            List<ClusterVO> clusterVOList = new ArrayList<>();
+            List<ServicePO> servicePOList = 
servicePONameMap.get(serviceDTO.getName());
+            if (!CollectionUtils.isEmpty(servicePOList)) {
+                for (ServicePO servicePO : servicePOList) {
+                    ClusterVO clusterVO = 
clusterVOMap.get(servicePO.getClusterId());
+                    clusterVOList.add(clusterVO);
+                }
+            }
+
+            res.add(new ServiceClusterVO(serviceDTO.getName(), clusterVOList));
         }
 
-        List<Long> clusterIds =
-                servicePOList.stream().map(ServicePO::getClusterId).toList();
-        List<ClusterPO> clusterPOList = clusterDao.findByIds(clusterIds);
-        return ClusterConverter.INSTANCE.fromPO2VO(clusterPOList);
+        return res;
     }
 }
diff --git 
a/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties 
b/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
index 07bfd6e7..c83cf2b4 100644
--- a/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
+++ b/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
@@ -32,6 +32,7 @@ cluster.not.found=Cluster not exist
 cluster.exists=Cluster already exists
 cluster.has.hosts=Cluster still has hosts, please remove them first
 cluster.has.services=Cluster still has services, please remove them first
+cluster.has.no.services=Cluster has no services, please add one first
 
 host.not.found=Host not exist
 host.assigned=Hosts [{0}] already assigned to another cluster
diff --git 
a/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties 
b/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
index ed7ecbc1..7b4b92d0 100644
--- a/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
+++ b/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
@@ -32,6 +32,7 @@ cluster.not.found=集群不存在
 cluster.exists=集群已存在
 cluster.has.hosts=集群上仍有主机,请先移除
 cluster.has.services=集群上仍有服务,请先移除
+cluster.has.no.services=集群上没有服务,请先添加
 
 host.not.found=主机不存在
 host.assigned=主机 [{0}] 已属于其他集群

Reply via email to