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

wuzhiguo 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 2f1e553c BIGTOP-4253: Refactor APIs for Stack (#96)
2f1e553c is described below

commit 2f1e553c6e7d610d3e7d42e3169a5819e6815a65
Author: Zhiguo Wu <[email protected]>
AuthorDate: Thu Oct 31 10:10:06 2024 +0800

    BIGTOP-4253: Refactor APIs for Stack (#96)
---
 .../apache/bigtop/manager/dao/po/ClusterPO.java    |   3 -
 .../org/apache/bigtop/manager/dao/po/StackPO.java  |  43 ---
 .../bigtop/manager/dao/repository/StackDao.java    |  30 --
 .../main/resources/mapper/mysql/StackMapper.xml    |  46 ----
 .../resources/mapper/postgresql/StackMapper.xml    |  46 ----
 .../manager/server/command/job/AbstractJob.java    |   3 -
 .../server/command/job/AbstractServiceJob.java     |  26 +-
 .../server/command/job/ServiceInstallJob.java      |   4 +-
 .../server/command/task/CacheFileUpdateTask.java   |  14 -
 .../validator/RequiredServicesValidator.java       |   9 +-
 .../server/command/validator/StackValidator.java   |  57 ----
 .../manager/server/controller/StackController.java |  17 --
 .../server/model/converter/ClusterConverter.java   |   9 -
 .../server/model/converter/ServiceConverter.java   |  12 -
 .../server/model/converter/StackConverter.java     |   6 -
 .../manager/server/model/dto/ServiceDTO.java       |   2 +
 .../bigtop/manager/server/model/dto/StackDTO.java  |  18 +-
 .../bigtop/manager/server/model/vo/ServiceVO.java  |   4 +-
 .../bigtop/manager/server/model/vo/StackVO.java    |   2 -
 .../manager/server/service/StackService.java       |   6 -
 .../server/service/impl/ClusterServiceImpl.java    |  14 +-
 .../server/service/impl/StackServiceImpl.java      |  57 +---
 .../manager/server/stack/StackInitializer.java     |  73 -----
 .../manager/server/stack/model/StackModel.java     |  51 ----
 .../manager/server/stack/xml/StackMetainfoXml.java |  37 ---
 .../manager/server/utils/StackConfigUtils.java     |   6 +-
 .../bigtop/manager/server/utils/StackUtils.java    | 306 ++++++++-------------
 .../src/main/resources/ddl/MySQL-DDL-CREATE.sql    |  33 +--
 .../main/resources/ddl/PostgreSQL-DDL-CREATE.sql   |  15 -
 .../resources/stacks/bigtop/3.3.0/metainfo.xml     |  61 ----
 .../main/resources/stacks/infra/1.0.0/metainfo.xml |  41 ---
 .../server/controller/StackControllerTest.java     |  28 --
 .../manager/server/service/ClusterServiceTest.java |  32 +--
 33 files changed, 160 insertions(+), 951 deletions(-)

diff --git 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/ClusterPO.java
 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/ClusterPO.java
index 3b70c0af..3076e22c 100644
--- 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/ClusterPO.java
+++ 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/ClusterPO.java
@@ -60,9 +60,6 @@ public class ClusterPO extends BasePO implements Serializable 
{
     @Column(name = "selected")
     private Boolean selected;
 
-    @Column(name = "stack_id")
-    private Long stackId;
-
     @Transient
     @Column(name = "stack_name")
     private String stackName;
diff --git 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/StackPO.java
 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/StackPO.java
deleted file mode 100644
index 5b7add25..00000000
--- 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/po/StackPO.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.dao.po;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
-import java.io.Serializable;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@Table(name = "stack")
-public class StackPO extends BasePO implements Serializable {
-
-    @Id
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "stack_name", nullable = false)
-    private String stackName;
-
-    @Column(name = "stack_version", nullable = false)
-    private String stackVersion;
-}
diff --git 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/StackDao.java
 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/StackDao.java
deleted file mode 100644
index 8523d2be..00000000
--- 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/StackDao.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
- *
- *   http://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.dao.repository;
-
-import org.apache.bigtop.manager.dao.po.StackPO;
-
-import org.apache.ibatis.annotations.Param;
-
-public interface StackDao extends BaseDao<StackPO> {
-
-    StackPO findByStackNameAndStackVersion(
-            @Param("stackName") String stackName, @Param("stackVersion") 
String stackVersion);
-}
diff --git a/bigtop-manager-dao/src/main/resources/mapper/mysql/StackMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/mysql/StackMapper.xml
deleted file mode 100644
index d654df90..00000000
--- a/bigtop-manager-dao/src/main/resources/mapper/mysql/StackMapper.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  ~ 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
-  ~
-  ~   http://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.
--->
-
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd";>
-<mapper namespace="org.apache.bigtop.manager.dao.repository.StackDao">
-
-    <sql id="baseColumns">
-        id, stack_name, stack_version
-    </sql>
-
-    <select id="findByStackNameAndStackVersion" 
resultType="org.apache.bigtop.manager.dao.po.StackPO">
-        select
-        <include refid="baseColumns"/>
-        from
-        stack
-        <where>
-            <if test="stackName!=null">
-                stack_name=#{stackName}
-            </if>
-            <if test="stackVersion!=null">
-                and stack_version=#{stackVersion}
-            </if>
-        </where>
-        limit 1
-    </select>
-
-</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/StackMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/StackMapper.xml
deleted file mode 100644
index d9da21ba..00000000
--- a/bigtop-manager-dao/src/main/resources/mapper/postgresql/StackMapper.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  ~ 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
-  ~
-  ~   http://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.
--->
-
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd";>
-<mapper namespace="org.apache.bigtop.manager.dao.repository.StackDao">
-
-    <sql id="baseColumns">
-        "id", "stack_name", "stack_version"
-    </sql>
-
-    <select id="findByStackNameAndStackVersion" 
resultType="org.apache.bigtop.manager.dao.po.StackPO">
-        select
-        <include refid="baseColumns"/>
-        from
-        stack
-        <where>
-            <if test="stackName!=null">
-                stack_name=#{stackName}
-            </if>
-            <if test="stackVersion!=null">
-                and stack_version=#{stackVersion}
-            </if>
-        </where>
-        limit 1
-    </select>
-
-</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
index 6ae1ee85..bf5d3475 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
@@ -26,7 +26,6 @@ import org.apache.bigtop.manager.dao.po.StagePO;
 import org.apache.bigtop.manager.dao.po.TaskPO;
 import org.apache.bigtop.manager.dao.repository.ClusterDao;
 import org.apache.bigtop.manager.dao.repository.JobDao;
-import org.apache.bigtop.manager.dao.repository.StackDao;
 import org.apache.bigtop.manager.dao.repository.StageDao;
 import org.apache.bigtop.manager.dao.repository.TaskDao;
 import org.apache.bigtop.manager.server.command.stage.Stage;
@@ -42,7 +41,6 @@ import java.util.concurrent.LinkedBlockingQueue;
 @Slf4j
 public abstract class AbstractJob implements Job {
 
-    protected StackDao stackDao;
     protected ClusterDao clusterDao;
     protected JobDao jobDao;
     protected StageDao stageDao;
@@ -70,7 +68,6 @@ public abstract class AbstractJob implements Job {
     }
 
     protected void injectBeans() {
-        this.stackDao = SpringContextHolder.getBean(StackDao.class);
         this.clusterDao = SpringContextHolder.getBean(ClusterDao.class);
 
         this.jobDao = SpringContextHolder.getBean(JobDao.class);
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractServiceJob.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractServiceJob.java
index 5192d611..9014fada 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractServiceJob.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractServiceJob.java
@@ -24,7 +24,6 @@ import org.apache.bigtop.manager.common.utils.JsonUtils;
 import org.apache.bigtop.manager.dao.po.ComponentPO;
 import org.apache.bigtop.manager.dao.po.HostComponentPO;
 import org.apache.bigtop.manager.dao.po.HostPO;
-import org.apache.bigtop.manager.dao.po.StackPO;
 import org.apache.bigtop.manager.dao.repository.ComponentDao;
 import org.apache.bigtop.manager.dao.repository.HostComponentDao;
 import org.apache.bigtop.manager.dao.repository.HostDao;
@@ -40,6 +39,7 @@ import 
org.apache.bigtop.manager.server.holder.SpringContextHolder;
 import org.apache.bigtop.manager.server.model.dto.ComponentDTO;
 import org.apache.bigtop.manager.server.model.dto.ComponentHostDTO;
 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.dto.command.ServiceCommandDTO;
 import org.apache.bigtop.manager.server.stack.dag.ComponentCommandWrapper;
 import org.apache.bigtop.manager.server.stack.dag.DAG;
@@ -57,9 +57,10 @@ public abstract class AbstractServiceJob extends AbstractJob 
{
     protected HostComponentDao hostComponentDao;
     protected HostDao hostDao;
 
-    protected String stackName;
-    protected String stackVersion;
-    protected DAG<String, ComponentCommandWrapper, DagGraphEdge> dag;
+    // TODO: temp code
+    protected String stackName = "bigtop";
+    protected String stackVersion = "3.3.0";
+    protected DAG<String, ComponentCommandWrapper, DagGraphEdge> dag = 
StackUtils.DAG;
 
     public AbstractServiceJob(JobContext jobContext) {
         super(jobContext);
@@ -77,18 +78,13 @@ public abstract class AbstractServiceJob extends 
AbstractJob {
     @Override
     protected void beforeCreateStages() {
         super.beforeCreateStages();
-        StackPO stackPO = stackDao.findById(clusterPO.getStackId());
-
-        stackName = stackPO.getStackName();
-        stackVersion = stackPO.getStackVersion();
-        dag = 
StackUtils.getStackDagMap().get(StackUtils.fullStackName(stackName, 
stackVersion));
     }
 
     protected StageContext createStageContext(String serviceName, String 
componentName, List<String> hostnames) {
         StageContext stageContext = 
StageContext.fromCommandDTO(jobContext.getCommandDTO());
 
-        ServiceDTO serviceDTO = StackUtils.getServiceDTO(stackName, 
stackVersion, serviceName);
-        ComponentDTO componentDTO = StackUtils.getComponentDTO(stackName, 
stackVersion, componentName);
+        ServiceDTO serviceDTO = StackUtils.getServiceDTO(serviceName);
+        ComponentDTO componentDTO = StackUtils.getComponentDTO(componentName);
 
         stageContext.setServiceDTO(serviceDTO);
         stageContext.setComponentDTO(componentDTO);
@@ -126,7 +122,7 @@ public abstract class AbstractServiceJob extends 
AbstractJob {
     }
 
     protected String findServiceNameByComponentName(String componentName) {
-        for (ServiceDTO serviceDTO : StackUtils.getServiceDTOList(stackName, 
stackVersion)) {
+        for (ServiceDTO serviceDTO : StackUtils.getServiceDTOList(new 
StackDTO(stackName, stackVersion))) {
             for (ComponentDTO componentDTO : serviceDTO.getComponents()) {
                 if (componentDTO.getComponentName().equals(componentName)) {
                     return serviceDTO.getServiceName();
@@ -138,17 +134,17 @@ public abstract class AbstractServiceJob extends 
AbstractJob {
     }
 
     protected Boolean isMasterComponent(String componentName) {
-        ComponentDTO componentDTO = StackUtils.getComponentDTO(stackName, 
stackVersion, componentName);
+        ComponentDTO componentDTO = StackUtils.getComponentDTO(componentName);
         return 
componentDTO.getCategory().equalsIgnoreCase(ComponentCategories.MASTER);
     }
 
     protected Boolean isSlaveComponent(String componentName) {
-        ComponentDTO componentDTO = StackUtils.getComponentDTO(stackName, 
stackVersion, componentName);
+        ComponentDTO componentDTO = StackUtils.getComponentDTO(componentName);
         return 
componentDTO.getCategory().equalsIgnoreCase(ComponentCategories.SLAVE);
     }
 
     protected Boolean isClientComponent(String componentName) {
-        ComponentDTO componentDTO = StackUtils.getComponentDTO(stackName, 
stackVersion, componentName);
+        ComponentDTO componentDTO = StackUtils.getComponentDTO(componentName);
         return 
componentDTO.getCategory().equalsIgnoreCase(ComponentCategories.CLIENT);
     }
 
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/ServiceInstallJob.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/ServiceInstallJob.java
index 100ccdf4..c701f8c7 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/ServiceInstallJob.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/ServiceInstallJob.java
@@ -144,7 +144,7 @@ public class ServiceInstallJob extends AbstractServiceJob {
 
         // 1. Persist service and components
         if (servicePO == null) {
-            ServiceDTO serviceDTO = StackUtils.getServiceDTO(stackName, 
stackVersion, serviceName);
+            ServiceDTO serviceDTO = StackUtils.getServiceDTO(serviceName);
             servicePO = ServiceConverter.INSTANCE.fromDTO2PO(serviceDTO, 
clusterPO);
             serviceDao.save(servicePO);
         }
@@ -158,7 +158,7 @@ public class ServiceInstallJob extends AbstractServiceJob {
             // 3. Persist component
             ComponentPO componentPO = 
componentDao.findByClusterIdAndComponentName(clusterId, componentName);
             if (componentPO == null) {
-                ComponentDTO componentDTO = 
StackUtils.getComponentDTO(stackName, stackVersion, componentName);
+                ComponentDTO componentDTO = 
StackUtils.getComponentDTO(componentName);
                 componentPO = 
ComponentConverter.INSTANCE.fromDTO2PO(componentDTO, servicePO, clusterPO);
                 componentDao.save(componentPO);
             }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/CacheFileUpdateTask.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/CacheFileUpdateTask.java
index 4d679065..70b969a4 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/CacheFileUpdateTask.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/CacheFileUpdateTask.java
@@ -48,12 +48,7 @@ import 
org.apache.bigtop.manager.server.holder.SpringContextHolder;
 import org.apache.bigtop.manager.server.model.converter.RepoConverter;
 import org.apache.bigtop.manager.server.model.dto.PropertyDTO;
 import org.apache.bigtop.manager.server.model.dto.RepoDTO;
-import org.apache.bigtop.manager.server.model.dto.ServiceDTO;
-import org.apache.bigtop.manager.server.model.dto.StackDTO;
 import org.apache.bigtop.manager.server.utils.StackConfigUtils;
-import org.apache.bigtop.manager.server.utils.StackUtils;
-
-import org.apache.commons.lang3.tuple.ImmutablePair;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 
@@ -213,11 +208,6 @@ public class CacheFileUpdateTask extends AbstractTask {
         userMap = new HashMap<>();
         settingsMap = new HashMap<>();
 
-        String fullStackName = 
StackUtils.fullStackName(taskContext.getStackName(), 
taskContext.getStackVersion());
-        ImmutablePair<StackDTO, List<ServiceDTO>> immutablePair =
-                StackUtils.getStackKeyMap().get(fullStackName);
-        StackDTO stackDTO = immutablePair.getLeft();
-
         Map<String, Object> properties = taskContext.getProperties();
 
         repoList = RepoConverter.INSTANCE.fromDTO2Message((List<RepoDTO>) 
properties.get("repoInfoList"));
@@ -225,10 +215,6 @@ public class CacheFileUpdateTask extends AbstractTask {
         clusterInfo.setClusterName(taskContext.getClusterName());
         clusterInfo.setStackName(taskContext.getStackName());
         clusterInfo.setStackVersion(taskContext.getStackVersion());
-        clusterInfo.setUserGroup(stackDTO.getUserGroup());
-        clusterInfo.setRepoTemplate(stackDTO.getRepoTemplate());
-        clusterInfo.setRoot(stackDTO.getRoot());
-        clusterInfo.setPackages(List.of(stackDTO.getPackages().split(",")));
 
         List<String> hostnames = (List<String>) properties.get("hostnames");
         hostMap.put(Constants.ALL_HOST_KEY, new HashSet<>(hostnames));
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/RequiredServicesValidator.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/RequiredServicesValidator.java
index 0daefc71..c2073fd0 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/RequiredServicesValidator.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/RequiredServicesValidator.java
@@ -19,7 +19,6 @@
 package org.apache.bigtop.manager.server.command.validator;
 
 import org.apache.bigtop.manager.common.enums.Command;
-import org.apache.bigtop.manager.dao.po.ClusterPO;
 import org.apache.bigtop.manager.dao.po.ServicePO;
 import org.apache.bigtop.manager.dao.repository.ClusterDao;
 import org.apache.bigtop.manager.dao.repository.ServiceDao;
@@ -37,6 +36,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.stereotype.Component;
 
 import jakarta.annotation.Resource;
+import java.util.HashSet;
 import java.util.List;
 
 @Component
@@ -59,15 +59,12 @@ public class RequiredServicesValidator implements 
CommandValidator {
         List<ServiceCommandDTO> serviceCommands = 
commandDTO.getServiceCommands();
 
         Long clusterId = commandDTO.getClusterId();
-        ClusterPO clusterPO = clusterDao.findByIdJoin(clusterId);
-        String stackName = clusterPO.getStackName();
-        String stackVersion = clusterPO.getStackVersion();
 
         List<String> serviceNames =
                 
serviceCommands.stream().map(ServiceCommandDTO::getServiceName).toList();
         for (ServiceCommandDTO serviceCommand : serviceCommands) {
             String serviceName = serviceCommand.getServiceName();
-            ServiceDTO serviceDTO = StackUtils.getServiceDTO(stackName, 
stackVersion, serviceName);
+            ServiceDTO serviceDTO = StackUtils.getServiceDTO(serviceName);
             List<String> requiredServices = serviceDTO.getRequiredServices();
             if (CollectionUtils.isEmpty(requiredServices)) {
                 return;
@@ -79,7 +76,7 @@ public class RequiredServicesValidator implements 
CommandValidator {
 
             requiredServices.removeAll(list);
 
-            if (!serviceNames.containsAll(requiredServices)) {
+            if (!new HashSet<>(serviceNames).containsAll(requiredServices)) {
                 throw new 
ApiException(ApiExceptionEnum.SERVICE_REQUIRED_NOT_FOUND, String.join(",", 
requiredServices));
             }
         }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/StackValidator.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/StackValidator.java
deleted file mode 100644
index 387462d5..00000000
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/StackValidator.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.StackPO;
-import org.apache.bigtop.manager.dao.repository.StackDao;
-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.bigtop.manager.server.model.dto.command.ClusterCommandDTO;
-
-import org.springframework.stereotype.Component;
-
-import jakarta.annotation.Resource;
-import java.util.List;
-
-@Component
-public class StackValidator implements CommandValidator {
-
-    @Resource
-    private StackDao stackDao;
-
-    @Override
-    public List<CommandIdentifier> getCommandIdentifiers() {
-        return List.of(new CommandIdentifier(CommandLevel.CLUSTER, 
Command.CREATE));
-    }
-
-    @Override
-    public void validate(ValidatorContext context) {
-        ClusterCommandDTO clusterCommand = 
context.getCommandDTO().getClusterCommand();
-        String stackName = clusterCommand.getStackName();
-        String stackVersion = clusterCommand.getStackVersion();
-
-        StackPO stackPO = stackDao.findByStackNameAndStackVersion(stackName, 
stackVersion);
-        if (stackPO == null) {
-            throw new ApiException(ApiExceptionEnum.STACK_NOT_FOUND);
-        }
-    }
-}
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 ef30f320..b6a9e967 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,14 +18,11 @@
  */
 package org.apache.bigtop.manager.server.controller;
 
-import org.apache.bigtop.manager.server.model.vo.ServiceComponentVO;
-import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
 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;
 
@@ -48,18 +45,4 @@ public class StackController {
     public ResponseEntity<List<StackVO>> list() {
         return ResponseEntity.success(stackService.list());
     }
-
-    @Operation(summary = "list", description = "List stacks components")
-    @GetMapping("/{stackName}/{stackVersion}/components")
-    public ResponseEntity<List<ServiceComponentVO>> components(
-            @PathVariable String stackName, @PathVariable String stackVersion) 
{
-        return ResponseEntity.success(stackService.components(stackName, 
stackVersion));
-    }
-
-    @Operation(summary = "list", description = "List stacks configurations")
-    @GetMapping("/{stackName}/{stackVersion}/configurations")
-    public ResponseEntity<List<ServiceConfigVO>> configurations(
-            @PathVariable String stackName, @PathVariable String stackVersion) 
{
-        return ResponseEntity.success(stackService.configurations(stackName, 
stackVersion));
-    }
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ClusterConverter.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ClusterConverter.java
index 70f90934..d9e86f62 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ClusterConverter.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ClusterConverter.java
@@ -19,17 +19,13 @@
 package org.apache.bigtop.manager.server.model.converter;
 
 import org.apache.bigtop.manager.dao.po.ClusterPO;
-import org.apache.bigtop.manager.dao.po.StackPO;
 import org.apache.bigtop.manager.server.config.MapStructSharedConfig;
 import org.apache.bigtop.manager.server.model.dto.ClusterDTO;
-import org.apache.bigtop.manager.server.model.dto.StackDTO;
 import org.apache.bigtop.manager.server.model.dto.command.ClusterCommandDTO;
 import org.apache.bigtop.manager.server.model.req.ClusterReq;
 import org.apache.bigtop.manager.server.model.vo.ClusterVO;
 
-import org.mapstruct.Context;
 import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 @Mapper(config = MapStructSharedConfig.class)
@@ -46,9 +42,4 @@ public interface ClusterConverter {
     ClusterDTO fromPO2DTO(ClusterPO clusterPO);
 
     ClusterVO fromEntity2VO(ClusterPO clusterPO);
-
-    @Mapping(target = "stackName", expression = "java(stackPO.getStackName())")
-    @Mapping(target = "stackVersion", expression = 
"java(stackPO.getStackVersion())")
-    @Mapping(target = "stackId", expression = "java(stackPO.getId())")
-    ClusterPO fromDTO2PO(ClusterDTO clusterDTO, StackDTO stackDTO, @Context 
StackPO stackPO);
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ServiceConverter.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ServiceConverter.java
index b12b8522..2abd3c52 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ServiceConverter.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/ServiceConverter.java
@@ -22,7 +22,6 @@ import org.apache.bigtop.manager.dao.po.ClusterPO;
 import org.apache.bigtop.manager.dao.po.ServicePO;
 import org.apache.bigtop.manager.server.config.MapStructSharedConfig;
 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.ServiceVO;
 import org.apache.bigtop.manager.server.stack.model.ServiceModel;
 
@@ -32,7 +31,6 @@ import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
-import java.util.stream.Collectors;
 
 @Mapper(
         uses = {ComponentConverter.class, ConverterTool.class},
@@ -51,15 +49,6 @@ public interface ServiceConverter {
 
     List<ServiceVO> fromDTO2VO(List<ServiceDTO> serviceDTOList);
 
-    @Mapping(target = "serviceGroup", source = "stackDTO.userGroup")
-    ServiceVO fromDTO2VO(ServiceDTO serviceDTO, StackDTO stackDTO);
-
-    default List<ServiceVO> fromDTO2VO(List<ServiceDTO> serviceDTOList, 
StackDTO stackDTO) {
-        return serviceDTOList.stream()
-                .map(serviceDTO -> fromDTO2VO(serviceDTO, stackDTO))
-                .collect(Collectors.toList());
-    }
-
     @Mapping(target = "serviceName", source = "name")
     @Mapping(target = "serviceDesc", source = "desc")
     @Mapping(target = "serviceVersion", source = "version")
@@ -67,7 +56,6 @@ public interface ServiceConverter {
     ServiceDTO fromModel2DTO(ServiceModel serviceModel);
 
     @Mapping(target = "requiredServices", source = "requiredServices", 
qualifiedByName = "json2List")
-    @Mapping(target = "serviceGroup", source = "userGroup")
     ServiceVO fromPO2VO(ServicePO servicePO);
 
     List<ServiceVO> fromPO2VO(List<ServicePO> servicePOList);
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/StackConverter.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/StackConverter.java
index 2db76ccd..e954e319 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/StackConverter.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/converter/StackConverter.java
@@ -18,11 +18,9 @@
  */
 package org.apache.bigtop.manager.server.model.converter;
 
-import org.apache.bigtop.manager.dao.po.StackPO;
 import org.apache.bigtop.manager.server.config.MapStructSharedConfig;
 import org.apache.bigtop.manager.server.model.dto.StackDTO;
 import org.apache.bigtop.manager.server.model.vo.StackVO;
-import org.apache.bigtop.manager.server.stack.model.StackModel;
 
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
@@ -32,9 +30,5 @@ public interface StackConverter {
 
     StackConverter INSTANCE = Mappers.getMapper(StackConverter.class);
 
-    StackVO fromPO2VO(StackPO stackPO);
-
     StackVO fromDTO2VO(StackDTO stackDTO);
-
-    StackDTO fromModel2DTO(StackModel stackModel);
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ServiceDTO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ServiceDTO.java
index cb742eee..f4440b4c 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ServiceDTO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ServiceDTO.java
@@ -39,5 +39,7 @@ public class ServiceDTO {
 
     private List<ComponentDTO> components;
 
+    private List<TypeConfigDTO> configs;
+
     private List<String> requiredServices;
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/StackDTO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/StackDTO.java
index 9ad94ac3..3c5fb0e5 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/StackDTO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/StackDTO.java
@@ -18,26 +18,16 @@
  */
 package org.apache.bigtop.manager.server.model.dto;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
-
-import java.util.List;
+import lombok.EqualsAndHashCode;
 
 @Data
+@AllArgsConstructor
+@EqualsAndHashCode
 public class StackDTO {
 
     private String stackName;
 
     private String stackVersion;
-
-    private String scope;
-
-    private String root;
-
-    private String userGroup;
-
-    private String packages;
-
-    private String repoTemplate;
-
-    private List<RepoDTO> repos;
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceVO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceVO.java
index 43109511..e82787bf 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceVO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/ServiceVO.java
@@ -39,7 +39,9 @@ public class ServiceVO {
 
     private String serviceUser;
 
-    private String serviceGroup;
+    private List<ComponentVO> components;
+
+    private List<TypeConfigVO> configs;
 
     private List<String> requiredServices;
 
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/StackVO.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/StackVO.java
index ac20407d..7073bf4f 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/StackVO.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/StackVO.java
@@ -30,6 +30,4 @@ public class StackVO {
     private String stackVersion;
 
     private List<ServiceVO> services;
-
-    private List<RepoVO> repos;
 }
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 3aac6c98..d010852e 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,8 +18,6 @@
  */
 package org.apache.bigtop.manager.server.service;
 
-import org.apache.bigtop.manager.server.model.vo.ServiceComponentVO;
-import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
 import org.apache.bigtop.manager.server.model.vo.StackVO;
 
 import java.util.List;
@@ -32,8 +30,4 @@ public interface StackService {
      * @return Stacks
      */
     List<StackVO> list();
-
-    List<ServiceComponentVO> components(String stackName, String stackVersion);
-
-    List<ServiceConfigVO> configurations(String stackName, String 
stackVersion);
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
index 3bc0403c..6c1982ea 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java
@@ -21,20 +21,16 @@ package org.apache.bigtop.manager.server.service.impl;
 import org.apache.bigtop.manager.common.enums.MaintainState;
 import org.apache.bigtop.manager.dao.po.ClusterPO;
 import org.apache.bigtop.manager.dao.po.RepoPO;
-import org.apache.bigtop.manager.dao.po.StackPO;
 import org.apache.bigtop.manager.dao.repository.ClusterDao;
 import org.apache.bigtop.manager.dao.repository.RepoDao;
-import org.apache.bigtop.manager.dao.repository.StackDao;
 import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
 import org.apache.bigtop.manager.server.exception.ApiException;
 import org.apache.bigtop.manager.server.model.converter.ClusterConverter;
 import org.apache.bigtop.manager.server.model.converter.RepoConverter;
 import org.apache.bigtop.manager.server.model.dto.ClusterDTO;
-import org.apache.bigtop.manager.server.model.dto.StackDTO;
 import org.apache.bigtop.manager.server.model.vo.ClusterVO;
 import org.apache.bigtop.manager.server.service.ClusterService;
 import org.apache.bigtop.manager.server.service.HostService;
-import org.apache.bigtop.manager.server.utils.StackUtils;
 
 import org.springframework.stereotype.Service;
 
@@ -54,9 +50,6 @@ public class ClusterServiceImpl implements ClusterService {
     @Resource
     private RepoDao repoDao;
 
-    @Resource
-    private StackDao stackDao;
-
     @Resource
     private HostService hostService;
 
@@ -74,12 +67,7 @@ public class ClusterServiceImpl implements ClusterService {
     @Override
     public ClusterVO save(ClusterDTO clusterDTO) {
         // Save cluster
-        StackPO stackPO =
-                
stackDao.findByStackNameAndStackVersion(clusterDTO.getStackName(), 
clusterDTO.getStackVersion());
-        StackDTO stackDTO = StackUtils.getStackKeyMap()
-                .get(StackUtils.fullStackName(clusterDTO.getStackName(), 
clusterDTO.getStackVersion()))
-                .getLeft();
-        ClusterPO clusterPO = ClusterConverter.INSTANCE.fromDTO2PO(clusterDTO, 
stackDTO, stackPO);
+        ClusterPO clusterPO = ClusterConverter.INSTANCE.fromDTO2PO(clusterDTO);
         clusterPO.setSelected(clusterDao.count() == 0);
         clusterPO.setState(MaintainState.UNINSTALLED.getName());
 
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 36bbef0c..e6b421f3 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,23 +18,15 @@
  */
 package org.apache.bigtop.manager.server.service.impl;
 
-import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
-import org.apache.bigtop.manager.server.exception.ApiException;
-import org.apache.bigtop.manager.server.model.converter.ComponentConverter;
 import org.apache.bigtop.manager.server.model.converter.ServiceConverter;
 import org.apache.bigtop.manager.server.model.converter.StackConverter;
-import org.apache.bigtop.manager.server.model.converter.TypeConfigConverter;
 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.dto.TypeConfigDTO;
-import org.apache.bigtop.manager.server.model.vo.ServiceComponentVO;
-import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
 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.lang3.tuple.ImmutablePair;
-
 import org.springframework.stereotype.Service;
 
 import lombok.extern.slf4j.Slf4j;
@@ -50,11 +42,14 @@ public class StackServiceImpl implements StackService {
     @Override
     public List<StackVO> list() {
         List<StackVO> stackVOList = new ArrayList<>();
-        Map<String, ImmutablePair<StackDTO, List<ServiceDTO>>> stackKeyMap = 
StackUtils.getStackKeyMap();
 
-        for (ImmutablePair<StackDTO, List<ServiceDTO>> pair : 
stackKeyMap.values()) {
-            StackDTO stackDTO = pair.left;
-            List<ServiceDTO> serviceDTOList = pair.right;
+        for (Map.Entry<StackDTO, List<ServiceDTO>> entry : 
StackUtils.STACK_SERVICE_MAP.entrySet()) {
+            StackDTO stackDTO = entry.getKey();
+            List<ServiceDTO> serviceDTOList = entry.getValue();
+            for (ServiceDTO serviceDTO : serviceDTOList) {
+                List<TypeConfigDTO> configs = 
StackUtils.SERVICE_CONFIG_MAP.get(serviceDTO.getServiceName());
+                serviceDTO.setConfigs(configs);
+            }
 
             StackVO stackVO = StackConverter.INSTANCE.fromDTO2VO(stackDTO);
             
stackVO.setServices(ServiceConverter.INSTANCE.fromDTO2VO(serviceDTOList));
@@ -63,42 +58,4 @@ public class StackServiceImpl implements StackService {
 
         return stackVOList;
     }
-
-    @Override
-    public List<ServiceComponentVO> components(String stackName, String 
stackVersion) {
-        List<ServiceComponentVO> list = new ArrayList<>();
-
-        ImmutablePair<StackDTO, List<ServiceDTO>> pair =
-                
StackUtils.getStackKeyMap().get(StackUtils.fullStackName(stackName, 
stackVersion));
-        if (pair == null) {
-            throw new ApiException(ApiExceptionEnum.STACK_NOT_FOUND);
-        }
-
-        List<ServiceDTO> serviceDTOList = pair.right;
-        for (ServiceDTO serviceDTO : serviceDTOList) {
-            ServiceComponentVO element = new ServiceComponentVO();
-            element.setServiceName(serviceDTO.getServiceName());
-            
element.setComponents(ComponentConverter.INSTANCE.fromDTO2VO(serviceDTO.getComponents()));
-            list.add(element);
-        }
-
-        return list;
-    }
-
-    @Override
-    public List<ServiceConfigVO> configurations(String stackName, String 
stackVersion) {
-        List<ServiceConfigVO> list = new ArrayList<>();
-        Map<String, Map<String, List<TypeConfigDTO>>> stackConfigMap = 
StackUtils.getStackConfigMap();
-        Map<String, List<TypeConfigDTO>> serviceConfigMap =
-                stackConfigMap.get(StackUtils.fullStackName(stackName, 
stackVersion));
-
-        for (Map.Entry<String, List<TypeConfigDTO>> entry : 
serviceConfigMap.entrySet()) {
-            ServiceConfigVO element = new ServiceConfigVO();
-            element.setServiceName(entry.getKey());
-            
element.setConfigs(TypeConfigConverter.INSTANCE.fromDTO2VO(entry.getValue()));
-            list.add(element);
-        }
-
-        return list;
-    }
 }
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/StackInitializer.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/StackInitializer.java
deleted file mode 100644
index 3604ba7a..00000000
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/StackInitializer.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.stack;
-
-import org.apache.bigtop.manager.dao.po.StackPO;
-import org.apache.bigtop.manager.dao.repository.StackDao;
-import org.apache.bigtop.manager.server.model.dto.ServiceDTO;
-import org.apache.bigtop.manager.server.model.dto.StackDTO;
-import org.apache.bigtop.manager.server.utils.StackUtils;
-
-import org.springframework.boot.context.event.ApplicationStartedEvent;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-import lombok.extern.slf4j.Slf4j;
-
-import jakarta.annotation.Nonnull;
-import jakarta.annotation.Resource;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Initialize the stack and persist to the database.
- * 1. Get All stacks, Parse the stack.yaml
- * 2. Check if the stack is already in the database
- * 3. Persist the stack to the database
- */
-@Slf4j
-@Component
-public class StackInitializer implements 
ApplicationListener<ApplicationStartedEvent> {
-
-    @Resource
-    private StackDao stackDao;
-
-    @Override
-    public void onApplicationEvent(@Nonnull ApplicationStartedEvent event) {
-        log.info("Stacks is initializing...");
-
-        Map<StackDTO, List<ServiceDTO>> stackMap = StackUtils.stackList();
-        for (Map.Entry<StackDTO, List<ServiceDTO>> entry : 
stackMap.entrySet()) {
-            StackDTO stackDTO = entry.getKey();
-            String stackName = stackDTO.getStackName();
-            String stackVersion = stackDTO.getStackVersion();
-
-            StackPO stackPO = 
stackDao.findByStackNameAndStackVersion(stackName, stackVersion);
-            if (stackPO == null) {
-                stackPO = new StackPO();
-                stackPO.setStackName(stackName);
-                stackPO.setStackVersion(stackVersion);
-
-                stackDao.save(stackPO);
-            }
-        }
-
-        log.info("Stacks is initialized!");
-    }
-}
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/model/StackModel.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/model/StackModel.java
deleted file mode 100644
index 776b9ea5..00000000
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/model/StackModel.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.stack.model;
-
-import lombok.Data;
-
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
-import jakarta.xml.bind.annotation.XmlElement;
-
-@Data
-@XmlAccessorType(XmlAccessType.FIELD)
-public class StackModel {
-
-    @XmlElement(name = "stack-name")
-    private String stackName;
-
-    @XmlElement(name = "stack-version")
-    private String stackVersion;
-
-    @XmlElement(name = "user-group")
-    private String userGroup;
-
-    /**
-     * The scope of the stack, should be one of 'global' or 'cluster'.
-     */
-    private String scope;
-
-    private String root;
-
-    private String packages;
-
-    @XmlElement(name = "repo-template")
-    private String repoTemplate;
-}
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/xml/StackMetainfoXml.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/xml/StackMetainfoXml.java
deleted file mode 100644
index 65ea7009..00000000
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/xml/StackMetainfoXml.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.stack.xml;
-
-import org.apache.bigtop.manager.server.stack.model.StackModel;
-
-import lombok.Data;
-
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
-import jakarta.xml.bind.annotation.XmlElement;
-import jakarta.xml.bind.annotation.XmlRootElement;
-
-@Data
-@XmlRootElement(name = "metainfo")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class StackMetainfoXml {
-
-    @XmlElement(name = "stack")
-    private StackModel stack;
-}
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackConfigUtils.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackConfigUtils.java
index 18ffc383..64e800e4 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackConfigUtils.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackConfigUtils.java
@@ -24,6 +24,8 @@ import 
org.apache.bigtop.manager.server.stack.model.AttrsModel;
 import org.apache.bigtop.manager.server.stack.model.PropertyModel;
 import org.apache.bigtop.manager.server.stack.xml.ConfigurationXml;
 
+import org.apache.commons.lang3.StringUtils;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -53,9 +55,9 @@ public class StackConfigUtils {
     private static PropertyDTO getPropertyDTO(PropertyModel propertyModel) {
         PropertyDTO propertyDTO = new PropertyDTO();
         propertyDTO.setDisplayName(propertyModel.getDisplayName());
-        propertyDTO.setDesc(propertyModel.getDesc());
+        propertyDTO.setDesc(StringUtils.strip(propertyModel.getDesc()));
         propertyDTO.setName(propertyModel.getName());
-        propertyDTO.setValue(propertyModel.getValue());
+        propertyDTO.setValue(StringUtils.strip(propertyModel.getValue()));
         if (propertyModel.getAttrs() != null) {
             AttrsModel attrsModel = propertyModel.getAttrs();
             AttrsDTO attrsDTO = new AttrsDTO();
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackUtils.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackUtils.java
index 86b7525c..b69d5b1a 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackUtils.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/utils/StackUtils.java
@@ -23,7 +23,6 @@ import org.apache.bigtop.manager.common.utils.JsonUtils;
 import org.apache.bigtop.manager.server.exception.ApiException;
 import org.apache.bigtop.manager.server.exception.ServerException;
 import org.apache.bigtop.manager.server.model.converter.ServiceConverter;
-import org.apache.bigtop.manager.server.model.converter.StackConverter;
 import org.apache.bigtop.manager.server.model.dto.ComponentDTO;
 import org.apache.bigtop.manager.server.model.dto.PropertyDTO;
 import org.apache.bigtop.manager.server.model.dto.ServiceDTO;
@@ -33,12 +32,10 @@ import 
org.apache.bigtop.manager.server.stack.dag.ComponentCommandWrapper;
 import org.apache.bigtop.manager.server.stack.dag.DAG;
 import org.apache.bigtop.manager.server.stack.dag.DagGraphEdge;
 import org.apache.bigtop.manager.server.stack.model.ServiceModel;
-import org.apache.bigtop.manager.server.stack.model.StackModel;
 import org.apache.bigtop.manager.server.stack.xml.ServiceMetainfoXml;
-import org.apache.bigtop.manager.server.stack.xml.StackMetainfoXml;
 
 import org.apache.commons.lang3.EnumUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.StringUtils;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
@@ -47,14 +44,10 @@ import lombok.extern.slf4j.Slf4j;
 import java.io.File;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 @Slf4j
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
@@ -62,8 +55,6 @@ public class StackUtils {
 
     private static final String ROLE_COMMAND_SPLIT = "-";
 
-    private static final String BIGTOP_MANAGER_STACK_PATH = 
"bigtop.manager.stack.path";
-
     private static final String META_FILE = "metainfo.xml";
 
     private static final String STACKS_FOLDER_NAME = "stacks";
@@ -76,175 +67,116 @@ public class StackUtils {
 
     private static final String DEPENDENCY_FILE_NAME = "order.json";
 
-    private static final Map<String, Map<String, List<String>>> 
STACK_DEPENDENCY_MAP = new HashMap<>();
-
-    private static final Map<String, Map<String, List<TypeConfigDTO>>> 
STACK_CONFIG_MAP = new HashMap<>();
+    public static final Map<String, List<TypeConfigDTO>> SERVICE_CONFIG_MAP = 
new HashMap<>();
 
-    private static final Map<String, ImmutablePair<StackDTO, 
List<ServiceDTO>>> STACK_KEY_MAP = new HashMap<>();
+    public static final Map<StackDTO, List<ServiceDTO>> STACK_SERVICE_MAP = 
new HashMap<>();
 
-    private static final Map<String, DAG<String, ComponentCommandWrapper, 
DagGraphEdge>> STACK_DAG_MAP =
-            new HashMap<>();
+    public static final DAG<String, ComponentCommandWrapper, DagGraphEdge> DAG 
= new DAG<>();
 
-    public static Map<String, Map<String, List<String>>> 
getStackDependencyMap() {
-        return Collections.unmodifiableMap(STACK_DEPENDENCY_MAP);
-    }
-
-    public static Map<String, Map<String, List<TypeConfigDTO>>> 
getStackConfigMap() {
-        return Collections.unmodifiableMap(STACK_CONFIG_MAP);
-    }
-
-    public static Map<String, ImmutablePair<StackDTO, List<ServiceDTO>>> 
getStackKeyMap() {
-        return Collections.unmodifiableMap(STACK_KEY_MAP);
-    }
-
-    public static Map<String, DAG<String, ComponentCommandWrapper, 
DagGraphEdge>> getStackDagMap() {
-        return Collections.unmodifiableMap(STACK_DAG_MAP);
+    static {
+        parseStack();
     }
 
     /**
-     * Parse stack file to generate stack model
      *
-     * @return stack model {@link StackModel}
      */
-    public static StackDTO parseStack(File versionFolder) {
-        StackMetainfoXml stackMetainfoXml = JaxbUtils.readFromPath(
-                versionFolder.getAbsolutePath() + File.separator + META_FILE, 
StackMetainfoXml.class);
-        return 
StackConverter.INSTANCE.fromModel2DTO(stackMetainfoXml.getStack());
+    private static void parseStack() {
+        File stacksFolder = loadStacksFolder();
+        File[] stackFolders = 
Optional.ofNullable(stacksFolder.listFiles()).orElse(new File[0]);
+
+        for (File stackFolder : stackFolders) {
+            String stackName = stackFolder.getName();
+            File[] versionFolders = 
Optional.ofNullable(stackFolder.listFiles()).orElse(new File[0]);
+
+            for (File versionFolder : versionFolders) {
+                String stackVersion = versionFolder.getName();
+                parseService(new StackDTO(stackName, stackVersion), 
versionFolder);
+            }
+        }
     }
 
     /**
      * Parse service file to generate service model
      *
-     * @param fullStackName full stack name
+     * @param stackDTO stackDTO
      * @return service model {@link ServiceModel}
      */
-    public static List<ServiceDTO> parseService(File versionFolder, String 
fullStackName) {
-        Map<String, List<TypeConfigDTO>> mergedConfigMap = new HashMap<>();
+    public static void parseService(StackDTO stackDTO, File versionFolder) {
         File[] files = new File(versionFolder.getAbsolutePath(), 
SERVICES_FOLDER_NAME).listFiles();
         List<ServiceDTO> services = new ArrayList<>();
 
         if (files != null) {
             for (File file : files) {
-                log.info("service dir: {}", file);
+                log.info("parsing service: {}", file.getName());
 
-                // metainfo.xml
-                ServiceMetainfoXml serviceMetainfoXml =
-                        JaxbUtils.readFromPath(file.getAbsolutePath() + "/" + 
META_FILE, ServiceMetainfoXml.class);
-                ServiceModel serviceModel = serviceMetainfoXml.getService();
-                ServiceDTO serviceDTO = 
ServiceConverter.INSTANCE.fromModel2DTO(serviceModel);
+                ServiceDTO serviceDTO = parseServiceMetaInfo(file);
                 services.add(serviceDTO);
 
-                // configurations
-                List<TypeConfigDTO> serviceConfigList = new ArrayList<>();
-                File configFolder = new File(file.getAbsolutePath(), 
CONFIGURATION_FOLDER);
-                if (configFolder.exists()) {
-                    for (File configFile :
-                            
Optional.ofNullable(configFolder.listFiles()).orElse(new File[0])) {
-                        String configPath = configFile.getAbsolutePath();
-                        String fileExtension = 
configPath.substring(configPath.lastIndexOf(".") + 1);
-                        if 
(fileExtension.equals(CONFIGURATION_FILE_EXTENSION)) {
-                            String typeName = configPath.substring(
-                                    configPath.lastIndexOf(File.separator) + 
1, configPath.lastIndexOf("."));
-
-                            List<PropertyDTO> properties = 
StackConfigUtils.loadConfig(configPath);
-                            TypeConfigDTO typeConfigDTO = new TypeConfigDTO();
-                            typeConfigDTO.setTypeName(typeName);
-                            typeConfigDTO.setProperties(properties);
-                            serviceConfigList.add(typeConfigDTO);
-                        }
-                    }
-                }
-
-                mergedConfigMap.put(serviceDTO.getServiceName(), 
serviceConfigList);
-
-                // order.json
-                File dependencyFile = new File(file.getAbsolutePath(), 
DEPENDENCY_FILE_NAME);
-                if (dependencyFile.exists()) {
-                    Map<String, List<String>> dependencyMap =
-                            
STACK_DEPENDENCY_MAP.computeIfAbsent(fullStackName, k -> new HashMap<>());
+                parseServiceConfigurations(file, serviceDTO.getServiceName());
 
-                    Map<String, List<String>> dependencyMapByFile = 
JsonUtils.readFromFile(dependencyFile);
-                    for (Map.Entry<String, List<String>> entry : 
dependencyMapByFile.entrySet()) {
-                        String blocked = entry.getKey();
-                        String fixedBlocked = 
blocked.split(ROLE_COMMAND_SPLIT)[0].toLowerCase()
-                                + ROLE_COMMAND_SPLIT
-                                + blocked.split(ROLE_COMMAND_SPLIT)[1];
-                        List<String> blockers = entry.getValue();
-                        List<String> fixedBlockers = blockers.stream()
-                                .map(x -> 
x.split(ROLE_COMMAND_SPLIT)[0].toLowerCase()
-                                        + ROLE_COMMAND_SPLIT
-                                        + x.split(ROLE_COMMAND_SPLIT)[1])
-                                .toList();
-
-                        dependencyMap.put(fixedBlocked, fixedBlockers);
-                    }
-                }
+                parseDag(file);
             }
-
-            STACK_CONFIG_MAP.put(fullStackName, mergedConfigMap);
         }
 
-        // log.info("Stack config map: {}", STACK_CONFIG_MAP);
-        log.info("Stack dependency map: {}", STACK_DEPENDENCY_MAP);
-        return services;
+        STACK_SERVICE_MAP.put(stackDTO, services);
     }
 
-    /**
-     * @return stack list map
-     */
-    public static Map<StackDTO, List<ServiceDTO>> stackList() {
-        File stacksFolder = loadStacksFolder();
-        File[] stackFolders = 
Optional.ofNullable(stacksFolder.listFiles()).orElse(new File[0]);
-        Map<StackDTO, List<ServiceDTO>> stackMap = new HashMap<>();
-
-        for (File stackFolder : stackFolders) {
-            String stackName = stackFolder.getName();
-            File[] versionFolders = 
Optional.ofNullable(stackFolder.listFiles()).orElse(new File[0]);
-
-            for (File versionFolder : versionFolders) {
-                String stackVersion = versionFolder.getName();
-                String fullStackName = fullStackName(stackName, stackVersion);
-                log.info("Parsing stack: {}", fullStackName);
-
-                checkStack(versionFolder);
-                StackDTO stackDTO = parseStack(versionFolder);
-                List<ServiceDTO> services = parseService(versionFolder, 
fullStackName);
-
-                stackMap.put(stackDTO, services);
+    private static ServiceDTO parseServiceMetaInfo(File file) {
+        ServiceMetainfoXml serviceMetainfoXml =
+                JaxbUtils.readFromPath(file.getAbsolutePath() + "/" + 
META_FILE, ServiceMetainfoXml.class);
+        ServiceModel serviceModel = serviceMetainfoXml.getService();
+        ServiceDTO serviceDTO = 
ServiceConverter.INSTANCE.fromModel2DTO(serviceModel);
+        
serviceDTO.setServiceDesc(StringUtils.strip(serviceDTO.getServiceDesc()));
+        return serviceDTO;
+    }
 
-                STACK_KEY_MAP.put(fullStackName, new ImmutablePair<>(stackDTO, 
services));
+    private static void parseServiceConfigurations(File file, String 
serviceName) {
+        List<TypeConfigDTO> typeConfigs = new ArrayList<>();
+        File configFolder = new File(file.getAbsolutePath(), 
CONFIGURATION_FOLDER);
+        if (configFolder.exists()) {
+            for (File configFile : 
Optional.ofNullable(configFolder.listFiles()).orElse(new File[0])) {
+                String configPath = configFile.getAbsolutePath();
+                String fileExtension = 
configPath.substring(configPath.lastIndexOf(".") + 1);
+                if (fileExtension.equals(CONFIGURATION_FILE_EXTENSION)) {
+                    String typeName = configPath.substring(
+                            configPath.lastIndexOf(File.separator) + 1, 
configPath.lastIndexOf("."));
+
+                    List<PropertyDTO> properties = 
StackConfigUtils.loadConfig(configPath);
+                    TypeConfigDTO typeConfigDTO = new TypeConfigDTO();
+                    typeConfigDTO.setTypeName(typeName);
+                    typeConfigDTO.setProperties(properties);
+                    typeConfigs.add(typeConfigDTO);
+                }
             }
         }
 
-        initializeDag();
-        return stackMap;
+        SERVICE_CONFIG_MAP.put(serviceName, typeConfigs);
     }
 
-    /**
-     * Initialize the DAG for each stack
-     */
-    private static void initializeDag() {
-        for (Map.Entry<String, Map<String, List<String>>> mapEntry :
-                StackUtils.getStackDependencyMap().entrySet()) {
-            String fullStackName = mapEntry.getKey();
-            DAG<String, ComponentCommandWrapper, DagGraphEdge> dag = new 
DAG<>();
-
-            for (Map.Entry<String, List<String>> entry : 
mapEntry.getValue().entrySet()) {
-                String blocked = entry.getKey();
-                List<String> blockers = entry.getValue();
-                addToDagNode(dag, blocked);
+    private static void parseDag(File file) {
+        File dependencyFile = new File(file.getAbsolutePath(), 
DEPENDENCY_FILE_NAME);
+        if (dependencyFile.exists()) {
+            Map<String, List<String>> dependencyMapByFile = 
JsonUtils.readFromFile(dependencyFile);
+            for (Map.Entry<String, List<String>> entry : 
dependencyMapByFile.entrySet()) {
+                String blocked = 
entry.getKey().split(ROLE_COMMAND_SPLIT)[0].toLowerCase()
+                        + ROLE_COMMAND_SPLIT
+                        + entry.getKey().split(ROLE_COMMAND_SPLIT)[1];
+                List<String> blockers = entry.getValue().stream()
+                        .map(x -> x.split(ROLE_COMMAND_SPLIT)[0].toLowerCase()
+                                + ROLE_COMMAND_SPLIT
+                                + x.split(ROLE_COMMAND_SPLIT)[1])
+                        .toList();
 
+                DAG.addNodeIfAbsent(blocked, getCommandWrapper(blocked));
                 for (String blocker : blockers) {
-                    addToDagNode(dag, blocker);
-                    dag.addEdge(blocker, blocked, new DagGraphEdge(blocker, 
blocked), false);
+                    DAG.addNodeIfAbsent(blocked, getCommandWrapper(blocked));
+                    DAG.addEdge(blocker, blocked, new DagGraphEdge(blocker, 
blocked), false);
                 }
             }
-
-            STACK_DAG_MAP.put(fullStackName, dag);
         }
     }
 
-    private static void addToDagNode(DAG<String, ComponentCommandWrapper, 
DagGraphEdge> dag, String roleCommand) {
+    private static ComponentCommandWrapper getCommandWrapper(String 
roleCommand) {
         String[] split = roleCommand.split(ROLE_COMMAND_SPLIT);
         String role = split[0];
         String command = split[1];
@@ -253,84 +185,72 @@ public class StackUtils {
             throw new ServerException("Unsupported command: " + command);
         }
 
-        ComponentCommandWrapper commandWrapper = new 
ComponentCommandWrapper(role, Command.valueOf(command));
-        dag.addNodeIfAbsent(roleCommand, commandWrapper);
+        return new ComponentCommandWrapper(role, Command.valueOf(command));
     }
 
     /**
      * Load stack folder as file
      */
     private static File loadStacksFolder() throws ApiException {
-        String stackPath = System.getProperty(BIGTOP_MANAGER_STACK_PATH);
-        stackPath = stackPath == null ? "" : stackPath;
+        URL url = 
StackUtils.class.getClassLoader().getResource(STACKS_FOLDER_NAME);
+        if (url == null) {
+            throw new ServerException("Can't find stack folder");
+        }
 
+        String stackPath = url.getPath();
         File file = new File(stackPath);
-        if (!file.exists() || !file.isDirectory()) {
-            URL url = 
StackUtils.class.getClassLoader().getResource(STACKS_FOLDER_NAME);
-            if (url == null) {
-                throw new ServerException("Can't find stack folder");
-            }
-
-            stackPath = url.getPath();
-            file = new File(stackPath);
-            if (!file.exists()) {
-                throw new ServerException("Can't find stack folder");
-            }
+        if (!file.exists()) {
+            throw new ServerException("Can't find stack folder");
         }
 
         log.info("stack file: {}", file);
         return file;
     }
 
-    /**
-     * Check stack file
-     *
-     * @param versionFolder stack version folder
-     */
-    private static void checkStack(File versionFolder) {
-        String[] list = versionFolder.list();
-        if (list == null || !Arrays.asList(list).contains(META_FILE)) {
-            throw new ServerException(
-                    "Missing metainfo.xml in stack version folder: " + 
versionFolder.getAbsolutePath());
+    public static StackDTO getServiceStack(String serviceName) {
+        for (Map.Entry<StackDTO, List<ServiceDTO>> entry : 
STACK_SERVICE_MAP.entrySet()) {
+            for (ServiceDTO serviceDTO : entry.getValue()) {
+                if (serviceDTO.getServiceName().equals(serviceName)) {
+                    return entry.getKey();
+                }
+            }
         }
-    }
 
-    /**
-     * Generate full stack name
-     *
-     * @param stackName    bigtop
-     * @param stackVersion 3.3.0
-     * @return {stackName}-{stackVersion} eg. bigtop-3.3.0
-     */
-    public static String fullStackName(String stackName, String stackVersion) {
-        return stackName + "-" + stackVersion;
+        throw new ServerException("Service not found: " + serviceName);
     }
 
-    public static List<ServiceDTO> getServiceDTOList(String stackName, String 
stackVersion) {
-        Map<String, ImmutablePair<StackDTO, List<ServiceDTO>>> stackKeyMap = 
StackUtils.getStackKeyMap();
-        ImmutablePair<StackDTO, List<ServiceDTO>> immutablePair =
-                stackKeyMap.get(StackUtils.fullStackName(stackName, 
stackVersion));
-        return immutablePair.getRight().stream().toList();
-    }
+    public static List<ServiceDTO> getServiceDTOList(StackDTO stackDTO) {
+        List<ServiceDTO> serviceDTOList = STACK_SERVICE_MAP.get(stackDTO);
+        if (serviceDTOList == null) {
+            throw new ServerException("Stack not found: " + stackDTO);
+        }
 
-    public static ServiceDTO getServiceDTO(String stackName, String 
stackVersion, String serviceName) {
-        Map<String, ServiceDTO> serviceNameToDTO = 
getServiceDTOList(stackName, stackVersion).stream()
-                .collect(Collectors.toMap(ServiceDTO::getServiceName, 
Function.identity()));
-        return serviceNameToDTO.get(serviceName);
+        return serviceDTOList;
     }
 
-    public static List<ComponentDTO> getComponentDTOList(String stackName, 
String stackVersion) {
-        Map<String, ImmutablePair<StackDTO, List<ServiceDTO>>> stackKeyMap = 
StackUtils.getStackKeyMap();
-        ImmutablePair<StackDTO, List<ServiceDTO>> immutablePair =
-                stackKeyMap.get(StackUtils.fullStackName(stackName, 
stackVersion));
-        return immutablePair.getRight().stream()
-                .flatMap(serviceDTO -> serviceDTO.getComponents().stream())
-                .toList();
+    public static ServiceDTO getServiceDTO(String serviceName) {
+        for (Map.Entry<StackDTO, List<ServiceDTO>> entry : 
STACK_SERVICE_MAP.entrySet()) {
+            for (ServiceDTO serviceDTO : entry.getValue()) {
+                if (serviceDTO.getServiceName().equals(serviceName)) {
+                    return serviceDTO;
+                }
+            }
+        }
+
+        throw new ServerException("Service not found: " + serviceName);
     }
 
-    public static ComponentDTO getComponentDTO(String stackName, String 
stackVersion, String componentName) {
-        Map<String, ComponentDTO> componentNameToDTO = 
getComponentDTOList(stackName, stackVersion).stream()
-                .collect(Collectors.toMap(ComponentDTO::getComponentName, 
Function.identity()));
-        return componentNameToDTO.get(componentName);
+    public static ComponentDTO getComponentDTO(String componentName) {
+        for (Map.Entry<StackDTO, List<ServiceDTO>> entry : 
STACK_SERVICE_MAP.entrySet()) {
+            for (ServiceDTO serviceDTO : entry.getValue()) {
+                for (ComponentDTO componentDTO : serviceDTO.getComponents()) {
+                    if (componentDTO.getComponentName().equals(componentName)) 
{
+                        return componentDTO;
+                    }
+                }
+            }
+        }
+
+        throw new ServerException("Component not found: " + componentName);
     }
 }
diff --git a/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql 
b/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
index 74055766..8a76fcc5 100644
--- a/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
+++ b/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
@@ -39,7 +39,7 @@ DEALLOCATE PREPARE statement;
 CREATE TABLE `audit_log`
 (
     `id`                BIGINT NOT NULL AUTO_INCREMENT,
-    `args`              LONGTEXT,
+    `args`              TEXT,
     `create_by`         BIGINT,
     `create_time`       DATETIME,
     `operation_desc`    VARCHAR(255),
@@ -84,10 +84,8 @@ CREATE TABLE `cluster`
     `state`         VARCHAR(255),
     `update_by`     BIGINT,
     `user_group`    VARCHAR(255),
-    `stack_id`      BIGINT,
     PRIMARY KEY (`id`),
-    UNIQUE KEY `uk_cluster_name` (`cluster_name`),
-    KEY `idx_cluster_stack_id` (`stack_id`)
+    UNIQUE KEY `uk_cluster_name` (`cluster_name`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
 
 CREATE TABLE `component`
@@ -98,7 +96,7 @@ CREATE TABLE `component`
     `component_name`  VARCHAR(255),
     `create_by`       BIGINT,
     `create_time`     DATETIME,
-    `custom_commands` LONGTEXT,
+    `custom_commands` TEXT,
     `display_name`    VARCHAR(255),
     `quick_link`      VARCHAR(255),
     `cardinality`     VARCHAR(255),
@@ -175,26 +173,13 @@ CREATE TABLE `repo`
     PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
 
-CREATE TABLE `stack`
-(
-    `id`             BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-    `stack_name`     VARCHAR(32) NOT NULL,
-    `stack_version`  VARCHAR(32) NOT NULL,
-    `create_time`    DATETIME DEFAULT NULL,
-    `update_time`    DATETIME DEFAULT NULL,
-    `create_by`      BIGINT,
-    `update_by`      BIGINT,
-    PRIMARY KEY (`id`),
-    UNIQUE KEY `uk_stack` (`stack_name`, `stack_version`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
-
 CREATE TABLE `task`
 (
     `id`              BIGINT NOT NULL AUTO_INCREMENT,
     `command`         VARCHAR(255),
     `component_name`  VARCHAR(255),
-    `content`         LONGTEXT,
-    `context`         LONGTEXT NOT NULL,
+    `content`         TEXT,
+    `context`         TEXT NOT NULL,
     `create_by`       BIGINT,
     `create_time`     DATETIME,
     `custom_command`  VARCHAR(255),
@@ -221,7 +206,7 @@ CREATE TABLE `job`
     `id`          BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
     `cluster_id`  BIGINT(20) UNSIGNED DEFAULT NULL,
     `state`       VARCHAR(32) NOT NULL,
-    `context`     LONGTEXT    NOT NULL,
+    `context`     TEXT    NOT NULL,
     `create_time` DATETIME DEFAULT NULL,
     `update_time` DATETIME DEFAULT NULL,
     `create_by`   BIGINT,
@@ -236,7 +221,7 @@ CREATE TABLE `type_config`
     `id`                BIGINT NOT NULL AUTO_INCREMENT,
     `create_by`         BIGINT,
     `create_time`       DATETIME,
-    `properties_json`   LONGTEXT,
+    `properties_json`   TEXT,
     `type_name`         VARCHAR(255),
     `update_by`         BIGINT,
     `update_time`       DATETIME,
@@ -284,7 +269,7 @@ CREATE TABLE `service_config`
 CREATE TABLE `setting`
 (
     `id`          BIGINT NOT NULL AUTO_INCREMENT,
-    `config_data` LONGTEXT,
+    `config_data` TEXT,
     `create_by`   BIGINT,
     `create_time` DATETIME,
     `type_name`   VARCHAR(255),
@@ -303,7 +288,7 @@ CREATE TABLE `stage`
     `create_time`    DATETIME DEFAULT NULL,
     `update_time`    DATETIME DEFAULT NULL,
     `component_name` VARCHAR(255),
-    `context`        LONGTEXT,
+    `context`        TEXT,
     `create_by`      BIGINT,
     `order`          INTEGER,
     `service_name`   VARCHAR(255),
diff --git 
a/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql 
b/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
index acc63f39..a0e53b29 100644
--- a/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
+++ b/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
@@ -67,7 +67,6 @@ CREATE TABLE cluster
     state         VARCHAR(255),
     update_by     BIGINT,
     user_group    VARCHAR(255),
-    stack_id      BIGINT,
     PRIMARY KEY (id),
     CONSTRAINT uk_cluster_name UNIQUE (cluster_name)
 );
@@ -78,7 +77,6 @@ COMMENT ON COLUMN cluster.cluster_type IS '1-Physical 
Machine, 2-Kubernetes';
 COMMENT ON COLUMN cluster.selected IS '0-Disable, 1-Enable';
 
 DROP INDEX IF EXISTS idx_cluster_stack_id;
-CREATE INDEX idx_cluster_stack_id ON cluster (stack_id);
 
 CREATE TABLE component
 (
@@ -178,19 +176,6 @@ CREATE TABLE repo
 
 COMMENT ON COLUMN repo.type IS '1-services, 2-tools';
 
-CREATE TABLE stack
-(
-    id            BIGINT CHECK (id > 0) NOT NULL GENERATED ALWAYS AS IDENTITY,
-    stack_name    VARCHAR(32)           NOT NULL,
-    stack_version VARCHAR(32)           NOT NULL,
-    create_time   TIMESTAMP(0) DEFAULT NULL,
-    update_time   TIMESTAMP(0) DEFAULT NULL,
-    create_by     BIGINT,
-    update_by     BIGINT,
-    PRIMARY KEY (id),
-    CONSTRAINT uk_stack UNIQUE (stack_name, stack_version)
-);
-
 CREATE TABLE task
 (
     id             BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
diff --git 
a/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/metainfo.xml 
b/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/metainfo.xml
deleted file mode 100644
index 810a82c2..00000000
--- a/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/metainfo.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  ~ 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.
--->
-
-<metainfo>
-    <stack>
-        <stack-name>bigtop</stack-name>
-        <stack-version>3.3.0</stack-version>
-        <user-group>hadoop</user-group>
-        <scope>cluster</scope>
-        <root>/opt</root>
-        <packages>curl,wget</packages>
-        <repo-template><![CDATA[
-[${repoId}]
-name=${repoName}
-<#if baseUrl?? >
-baseurl=${baseUrl}
-<#else>
-mirrorlist=${mirrorList}
-</#if>
-path=/
-enabled=1
-gpgcheck=0
-]]>
-        </repo-template>
-        <repos>
-            <repo>
-                <repo-id>Bigtop-3.3.0</repo-id>
-                <repo-name>Bigtop-3.3.0 for RockyLinux-8 x86_64</repo-name>
-                <repo-type>binary</repo-type>
-                <os>rocky8</os>
-                <arch>x86_64</arch>
-                
<base-url>http://123.56.2.244/bigtop/3.3.0/rocky8/x86_64/</base-url>
-            </repo>
-            <repo>
-                <repo-id>Bigtop-3.3.0</repo-id>
-                <repo-name>Bigtop-3.3.0 for openEuler-22.03 x86_64</repo-name>
-                <repo-type>binary</repo-type>
-                <os>openeuler22</os>
-                <arch>x86_64</arch>
-                
<base-url>http://123.56.2.244/bigtop/3.3.0/openeuler22/x86_64/</base-url>
-            </repo>
-        </repos>
-    </stack>
-</metainfo>
\ No newline at end of file
diff --git 
a/bigtop-manager-server/src/main/resources/stacks/infra/1.0.0/metainfo.xml 
b/bigtop-manager-server/src/main/resources/stacks/infra/1.0.0/metainfo.xml
deleted file mode 100644
index 74a38f3d..00000000
--- a/bigtop-manager-server/src/main/resources/stacks/infra/1.0.0/metainfo.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  ~ 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.
--->
-
-<metainfo>
-    <stack>
-        <stack-name>infra</stack-name>
-        <stack-version>1.0.0</stack-version>
-        <user-group>hadoop</user-group>
-        <scope>global</scope>
-        <root>/opt</root>
-        <packages>curl,wget</packages>
-        <repo-template />
-        <repos>
-            <repo>
-                <repo-id>Infra-1.0.0</repo-id>
-                <repo-name>Infra-1.0.0 for RockyLinux-8 x86_64</repo-name>
-                <repo-type>tarball</repo-type>
-                <os>rocky8</os>
-                <arch>x86_64</arch>
-                <base-url>http://123.56.2.244/infra/1.0.0/tarballs/</base-url>
-            </repo>
-        </repos>
-    </stack>
-</metainfo>
\ No newline at end of file
diff --git 
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/StackControllerTest.java
 
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/StackControllerTest.java
index 60b072f4..99a333b6 100644
--- 
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/StackControllerTest.java
+++ 
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/controller/StackControllerTest.java
@@ -18,8 +18,6 @@
  */
 package org.apache.bigtop.manager.server.controller;
 
-import org.apache.bigtop.manager.server.model.vo.ServiceComponentVO;
-import org.apache.bigtop.manager.server.model.vo.ServiceConfigVO;
 import org.apache.bigtop.manager.server.model.vo.StackVO;
 import org.apache.bigtop.manager.server.service.StackService;
 import org.apache.bigtop.manager.server.utils.MessageSourceUtils;
@@ -75,30 +73,4 @@ class StackControllerTest {
         assertTrue(response.isSuccess());
         assertEquals(stacks, response.getData());
     }
-
-    @Test
-    void componentsReturnsAllComponentsForValidStack() {
-        String stackName = "bigtop";
-        String stackVersion = "1.0.0";
-        List<ServiceComponentVO> components = Arrays.asList(new 
ServiceComponentVO(), new ServiceComponentVO());
-        when(stackService.components(stackName, 
stackVersion)).thenReturn(components);
-
-        ResponseEntity<List<ServiceComponentVO>> response = 
stackController.components(stackName, stackVersion);
-
-        assertTrue(response.isSuccess());
-        assertEquals(components, response.getData());
-    }
-
-    @Test
-    void configurationsReturnsAllConfigurationsForValidStack() {
-        String stackName = "bigtop";
-        String stackVersion = "1.0.0";
-        List<ServiceConfigVO> configurations = Arrays.asList(new 
ServiceConfigVO(), new ServiceConfigVO());
-        when(stackService.configurations(stackName, 
stackVersion)).thenReturn(configurations);
-
-        ResponseEntity<List<ServiceConfigVO>> response = 
stackController.configurations(stackName, stackVersion);
-
-        assertTrue(response.isSuccess());
-        assertEquals(configurations, response.getData());
-    }
 }
diff --git 
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
 
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
index 42535ed0..7abda725 100644
--- 
a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
+++ 
b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/service/ClusterServiceTest.java
@@ -20,11 +20,8 @@
 package org.apache.bigtop.manager.server.service;
 
 import org.apache.bigtop.manager.dao.po.ClusterPO;
-import org.apache.bigtop.manager.dao.po.RepoPO;
-import org.apache.bigtop.manager.dao.po.StackPO;
 import org.apache.bigtop.manager.dao.repository.ClusterDao;
 import org.apache.bigtop.manager.dao.repository.RepoDao;
-import org.apache.bigtop.manager.dao.repository.StackDao;
 import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
 import org.apache.bigtop.manager.server.exception.ApiException;
 import org.apache.bigtop.manager.server.model.dto.ClusterDTO;
@@ -32,7 +29,6 @@ import org.apache.bigtop.manager.server.model.dto.RepoDTO;
 import org.apache.bigtop.manager.server.model.dto.ServiceDTO;
 import org.apache.bigtop.manager.server.model.dto.StackDTO;
 import org.apache.bigtop.manager.server.service.impl.ClusterServiceImpl;
-import org.apache.bigtop.manager.server.utils.StackUtils;
 
 import org.apache.commons.lang3.tuple.ImmutablePair;
 
@@ -41,20 +37,15 @@ 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.junit.jupiter.MockitoExtension;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.CALLS_REAL_METHODS;
-import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
 
 @ExtendWith(MockitoExtension.class)
@@ -64,9 +55,6 @@ public class ClusterServiceTest {
     @Mock
     private ClusterDao clusterDao;
 
-    @Mock
-    private StackDao stackDao;
-
     @Mock
     private RepoDao repoDao;
 
@@ -93,11 +81,8 @@ public class ClusterServiceTest {
         RepoDTO repoDTO = new RepoDTO();
         repoDTO.setArch("x86_64");
         clusterDTO.setRepoInfoList(List.of(repoDTO));
-        StackDTO stackDTO = new StackDTO();
+        StackDTO stackDTO = new StackDTO(clusterDTO.getStackName(), 
clusterDTO.getStackVersion());
         stackDTO.setStackName("TestStack");
-        mockStackKeyMap.put(
-                StackUtils.fullStackName(clusterDTO.getStackName(), 
clusterDTO.getStackVersion()),
-                new ImmutablePair<>(stackDTO, new ArrayList<>()));
     }
 
     @Test
@@ -116,19 +101,4 @@ public class ClusterServiceTest {
         clusterDTO.setClusterName(CLUSTER_NAME);
         assert clusterService.update(1L, 
clusterDTO).getClusterName().equals(CLUSTER_NAME);
     }
-
-    @Test
-    public void testSave() {
-        when(stackDao.findByStackNameAndStackVersion(any(), 
any())).thenReturn(new StackPO());
-        when(hostService.batchSave(any(), any())).thenReturn(null);
-        RepoPO repoPO = new RepoPO();
-        repoPO.setArch("x86_64");
-        when(repoDao.findAllByClusterId(any())).thenReturn(List.of(repoPO));
-        try (MockedStatic<StackUtils> mockedStackUtils = 
mockStatic(StackUtils.class, CALLS_REAL_METHODS)) {
-            
mockedStackUtils.when(StackUtils::getStackKeyMap).thenReturn(mockStackKeyMap);
-            clusterService.save(clusterDTO);
-            
when(clusterDao.findByClusterName(any())).thenReturn(Optional.ofNullable(clusterPO));
-            clusterService.save(clusterDTO);
-        }
-    }
 }


Reply via email to