From b0af891b411745eb2fa4b88a002db2d49468ab02 Mon Sep 17 00:00:00 2001 From: Zhiguo Wu Date: Tue, 16 Jul 2024 16:54:37 +0800 Subject: [PATCH 1/4] BIGTOP-4163: Add quick links for service --- .../manager/agent/utils/LogFileUtils.java | 4 +- .../manager/common/utils/JsonUtils.java | 18 ++++++ .../bigtop/manager/dao/entity/Component.java | 3 + .../bigtop/manager/dao/entity/Service.java | 2 +- .../server/controller/SseController.java | 4 +- .../server/model/dto/ComponentDTO.java | 2 + .../server/model/dto/QuickLinkDTO.java | 35 +++++++++++ .../server/model/mapper/ComponentMapper.java | 1 + .../manager/server/model/vo/QuickLinkVO.java | 29 +++++++++ .../manager/server/model/vo/ServiceVO.java | 2 + .../service/impl/ServiceServiceImpl.java | 62 ++++++++++++++++++- .../server/stack/pojo/ComponentModel.java | 3 + .../server/stack/pojo/QuickLinkModel.java | 25 +++++++- .../bigtop/3.3.0/services/hdfs/metainfo.xml | 7 +++ .../bigtop/3.3.0/services/yarn/metainfo.xml | 7 +++ .../nop/1.0.0/services/zookeeper/metainfo.xml | 7 +++ bigtop-manager-ui/src/api/service/types.ts | 6 ++ .../src/locales/en_US/service.ts | 3 +- .../src/locales/zh_CN/service.ts | 3 +- bigtop-manager-ui/src/pages/service/index.vue | 38 ++++++++---- 20 files changed, 240 insertions(+), 21 deletions(-) create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/QuickLinkDTO.java create mode 100644 bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/QuickLinkVO.java diff --git a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/utils/LogFileUtils.java b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/utils/LogFileUtils.java index e87929a4..de3f482c 100644 --- a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/utils/LogFileUtils.java +++ b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/utils/LogFileUtils.java @@ -18,6 +18,8 @@ */ package org.apache.bigtop.manager.agent.utils; +import org.apache.bigtop.manager.common.utils.Environments; + import org.apache.commons.lang3.SystemUtils; import java.io.File; @@ -26,7 +28,7 @@ public class LogFileUtils { public static String getLogFilePath(Long taskId) { String baseDir; - if (SystemUtils.IS_OS_WINDOWS) { + if (Environments.isDevMode()) { baseDir = SystemUtils.getUserDir().getPath(); } else { File file = new File(LogFileUtils.class diff --git a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/utils/JsonUtils.java b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/utils/JsonUtils.java index 787d369c..963b48a3 100644 --- a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/utils/JsonUtils.java +++ b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/utils/JsonUtils.java @@ -18,6 +18,7 @@ */ package org.apache.bigtop.manager.common.utils; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; @@ -34,6 +35,7 @@ public class JsonUtils { static { OBJECTMAPPER = new ObjectMapper(); OBJECTMAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + OBJECTMAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); } public static void writeToFile(String fileName, T obj) { @@ -73,6 +75,10 @@ public static T readFromFile(File file, TypeReference typeReference) { } public static T readFromString(String json) { + if (json == null) { + return null; + } + try { return OBJECTMAPPER.readValue(json, new TypeReference<>() {}); } catch (Exception e) { @@ -81,6 +87,10 @@ public static T readFromString(String json) { } public static T readFromString(String json, TypeReference typeReference) { + if (json == null) { + return null; + } + try { return OBJECTMAPPER.readValue(json, typeReference); } catch (Exception e) { @@ -89,6 +99,10 @@ public static T readFromString(String json, TypeReference typeReference) } public static T readFromString(String json, Class clazz) { + if (json == null) { + return null; + } + try { return OBJECTMAPPER.readValue(json, clazz); } catch (Exception e) { @@ -105,6 +119,10 @@ public static JsonNode readTree(String filename) { } public static String writeAsString(T obj) { + if (obj == null) { + return null; + } + try { return OBJECTMAPPER.writeValueAsString(obj); } catch (Exception e) { diff --git a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Component.java b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Component.java index e7597e5f..a2411c4a 100644 --- a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Component.java +++ b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Component.java @@ -81,6 +81,9 @@ public class Component extends BaseEntity { @Column(name = "category") private String category; + @Column(name = "quick_link") + private String quickLink; + @ManyToOne @JoinColumn(name = "service_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) private Service service; diff --git a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Service.java b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Service.java index af9bcd83..eca5499e 100644 --- a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Service.java +++ b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/entity/Service.java @@ -79,7 +79,7 @@ public class Service extends BaseEntity { @Column(name = "service_group") private String serviceGroup; - @Column(name = "required_service") + @Column(name = "required_services") private String requiredServices; @ManyToOne diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java index 7ed8642d..9309a74f 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java @@ -44,8 +44,8 @@ public class SseController { @Operation(summary = "get task log", description = "Get a task log") @GetMapping("/tasks/{id}/log") public SseEmitter log(@PathVariable Long id, @PathVariable Long clusterId) { - // Default timeout to 5 minutes - SseEmitter emitter = new SseEmitter(5 * 60 * 1000L); + // Default timeout to 30 minutes + SseEmitter emitter = new SseEmitter(30 * 60 * 1000L); Flux flux = Flux.create(sink -> taskLogService.registerSink(id, sink), FluxSink.OverflowStrategy.BUFFER); diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ComponentDTO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ComponentDTO.java index 3589161f..8f42108a 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ComponentDTO.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/ComponentDTO.java @@ -36,4 +36,6 @@ public class ComponentDTO { private ScriptDTO commandScript; private List customCommands; + + private QuickLinkDTO quickLink; } diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/QuickLinkDTO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/QuickLinkDTO.java new file mode 100644 index 00000000..9db2a095 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/dto/QuickLinkDTO.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.server.model.dto; + +import lombok.Data; + +@Data +public class QuickLinkDTO { + + private String displayName; + + private String httpPortProperty; + + private String httpPortDefault; + + private String httpsPortProperty; + + private String httpsPortDefault; +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/mapper/ComponentMapper.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/mapper/ComponentMapper.java index 43cec48f..961967fd 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/mapper/ComponentMapper.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/mapper/ComponentMapper.java @@ -39,6 +39,7 @@ public interface ComponentMapper { @Mapping(target = "commandScript", source = "commandScript", qualifiedByName = "obj2Json") @Mapping(target = "customCommands", source = "customCommands", qualifiedByName = "obj2Json") + @Mapping(target = "quickLink", source = "quickLink", qualifiedByName = "obj2Json") @Mapping(target = "service", expression = "java(service)") @Mapping(target = "cluster", expression = "java(cluster)") Component fromDTO2Entity(ComponentDTO componentDTO, @Context Service service, @Context Cluster cluster); diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/QuickLinkVO.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/QuickLinkVO.java new file mode 100644 index 00000000..45670939 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/QuickLinkVO.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.server.model.vo; + +import lombok.Data; + +@Data +public class QuickLinkVO { + + private String displayName; + + private String url; +} 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 568fb4ab..43109511 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 @@ -46,4 +46,6 @@ public class ServiceVO { private Boolean isClient; private Boolean isHealthy; + + private List quickLinks; } 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 63fbbaab..8a139173 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 @@ -20,14 +20,28 @@ import org.apache.bigtop.manager.common.constants.ComponentCategories; import org.apache.bigtop.manager.common.enums.MaintainState; +import org.apache.bigtop.manager.common.utils.JsonUtils; +import org.apache.bigtop.manager.dao.entity.Cluster; +import org.apache.bigtop.manager.dao.entity.Component; +import org.apache.bigtop.manager.dao.entity.Host; import org.apache.bigtop.manager.dao.entity.HostComponent; import org.apache.bigtop.manager.dao.entity.Service; +import org.apache.bigtop.manager.dao.entity.ServiceConfig; +import org.apache.bigtop.manager.dao.entity.TypeConfig; import org.apache.bigtop.manager.dao.repository.HostComponentRepository; +import org.apache.bigtop.manager.dao.repository.ServiceConfigRepository; import org.apache.bigtop.manager.dao.repository.ServiceRepository; +import org.apache.bigtop.manager.server.model.dto.PropertyDTO; +import org.apache.bigtop.manager.server.model.dto.QuickLinkDTO; +import org.apache.bigtop.manager.server.model.dto.TypeConfigDTO; import org.apache.bigtop.manager.server.model.mapper.ServiceMapper; +import org.apache.bigtop.manager.server.model.mapper.TypeConfigMapper; +import org.apache.bigtop.manager.server.model.vo.QuickLinkVO; import org.apache.bigtop.manager.server.model.vo.ServiceVO; import org.apache.bigtop.manager.server.service.ServiceService; +import org.apache.commons.lang3.StringUtils; + import lombok.extern.slf4j.Slf4j; import jakarta.annotation.Resource; @@ -46,6 +60,9 @@ public class ServiceServiceImpl implements ServiceService { @Resource private HostComponentRepository hostComponentRepository; + @Resource + private ServiceConfigRepository serviceConfigRepository; + @Override public List list(Long clusterId) { List res = new ArrayList<>(); @@ -58,11 +75,20 @@ public List list(Long clusterId) { List hostComponents = entry.getValue(); Service service = hostComponents.get(0).getComponent().getService(); ServiceVO serviceVO = ServiceMapper.INSTANCE.fromEntity2VO(service); + serviceVO.setQuickLinks(new ArrayList<>()); boolean isHealthy = true; boolean isClient = true; for (HostComponent hostComponent : hostComponents) { - String category = hostComponent.getComponent().getCategory(); + Component component = hostComponent.getComponent(); + + String quickLink = component.getQuickLink(); + if (StringUtils.isNotBlank(quickLink)) { + QuickLinkVO quickLinkVO = resolveQuickLink(hostComponent, quickLink); + serviceVO.getQuickLinks().add(quickLinkVO); + } + + String category = component.getCategory(); if (!category.equalsIgnoreCase(ComponentCategories.CLIENT)) { isClient = false; } @@ -88,4 +114,38 @@ public ServiceVO get(Long id) { Service service = serviceRepository.findById(id).orElse(new Service()); return ServiceMapper.INSTANCE.fromEntity2VO(service); } + + private QuickLinkVO resolveQuickLink(HostComponent hostComponent, String quickLinkJson) { + QuickLinkVO quickLinkVO = new QuickLinkVO(); + + QuickLinkDTO quickLinkDTO = JsonUtils.readFromString(quickLinkJson, QuickLinkDTO.class); + quickLinkVO.setDisplayName(quickLinkDTO.getDisplayName()); + + Component component = hostComponent.getComponent(); + Cluster cluster = component.getCluster(); + Host host = hostComponent.getHost(); + Service service = component.getService(); + ServiceConfig serviceConfig = + serviceConfigRepository.findByClusterAndServiceAndSelectedIsTrue(cluster, service); + List typeConfigs = serviceConfig.getConfigs(); + + // Use HTTP for now, need to handle https in the future + for (TypeConfig typeConfig : typeConfigs) { + TypeConfigDTO typeConfigDTO = TypeConfigMapper.INSTANCE.fromEntity2DTO(typeConfig); + for (PropertyDTO propertyDTO : typeConfigDTO.getProperties()) { + if (propertyDTO.getName().equals(quickLinkDTO.getHttpPortProperty())) { + String port = propertyDTO.getValue().contains(":") + ? propertyDTO.getValue().split(":")[1] + : propertyDTO.getValue(); + String url = "http://" + host.getHostname() + ":" + port; + quickLinkVO.setUrl(url); + return quickLinkVO; + } + } + } + + String url = "http://" + host.getHostname() + ":" + quickLinkDTO.getHttpPortDefault(); + quickLinkVO.setUrl(url); + return quickLinkVO; + } } diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/ComponentModel.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/ComponentModel.java index ece81ab3..10c5416a 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/ComponentModel.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/ComponentModel.java @@ -46,4 +46,7 @@ public class ComponentModel { @XmlElementWrapper(name = "custom-commands") @XmlElements(@XmlElement(name = "custom-command")) private List customCommands; + + @XmlElement(name = "quick-link") + private QuickLinkModel quickLink; } diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/QuickLinkModel.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/QuickLinkModel.java index e688cbfa..1afec138 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/QuickLinkModel.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/stack/pojo/QuickLinkModel.java @@ -18,4 +18,27 @@ */ package org.apache.bigtop.manager.server.stack.pojo; -public class QuickLinkModel {} +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import lombok.Data; + +@Data +@XmlAccessorType(XmlAccessType.FIELD) +public class QuickLinkModel { + + @XmlElement(name = "display-name") + private String displayName; + + @XmlElement(name = "http-port-property") + private String httpPortProperty; + + @XmlElement(name = "http-port-default") + private String httpPortDefault; + + @XmlElement(name = "https-port-property") + private String httpsPortProperty; + + @XmlElement(name = "https-port-default") + private String httpsPortDefault; +} diff --git a/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/hdfs/metainfo.xml b/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/hdfs/metainfo.xml index 2d4f9f05..c2fc5188 100644 --- a/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/hdfs/metainfo.xml +++ b/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/hdfs/metainfo.xml @@ -57,6 +57,13 @@ + + NameNode UI + dfs.namenode.http-address + 50070 + dfs.namenode.http-address + 50470 + datanode diff --git a/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/yarn/metainfo.xml b/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/yarn/metainfo.xml index d3fc2243..44ea8ffe 100644 --- a/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/yarn/metainfo.xml +++ b/bigtop-manager-server/src/main/resources/stacks/bigtop/3.3.0/services/yarn/metainfo.xml @@ -57,6 +57,13 @@ + + ResourceManager UI + yarn.resourcemanager.webapp.address + 8088 + yarn.resourcemanager.webapp.https.address + 8090 + nodemanager diff --git a/bigtop-manager-server/src/main/resources/stacks/nop/1.0.0/services/zookeeper/metainfo.xml b/bigtop-manager-server/src/main/resources/stacks/nop/1.0.0/services/zookeeper/metainfo.xml index 97b88cb6..55db55e8 100644 --- a/bigtop-manager-server/src/main/resources/stacks/nop/1.0.0/services/zookeeper/metainfo.xml +++ b/bigtop-manager-server/src/main/resources/stacks/nop/1.0.0/services/zookeeper/metainfo.xml @@ -42,6 +42,13 @@ java 1200 + + ZooKeeper UI(Test) + admin.serverPort + 9393 + admin.serverPort + 9393 + diff --git a/bigtop-manager-ui/src/api/service/types.ts b/bigtop-manager-ui/src/api/service/types.ts index d4669ae3..d6a5d0d2 100644 --- a/bigtop-manager-ui/src/api/service/types.ts +++ b/bigtop-manager-ui/src/api/service/types.ts @@ -28,4 +28,10 @@ export interface ServiceVO { serviceGroup?: string isClient?: boolean isHealthy?: boolean + quickLinks?: QuickLinkVO[] +} + +export interface QuickLinkVO { + displayName: string + url: string } diff --git a/bigtop-manager-ui/src/locales/en_US/service.ts b/bigtop-manager-ui/src/locales/en_US/service.ts index d003f775..06cb8452 100644 --- a/bigtop-manager-ui/src/locales/en_US/service.ts +++ b/bigtop-manager-ui/src/locales/en_US/service.ts @@ -37,5 +37,6 @@ export default { summary: 'Summary', config: 'Config', components: 'Components', - quicklinks: 'Quick Links' + quick_links: 'Quick Links', + no_link: 'No Link' } diff --git a/bigtop-manager-ui/src/locales/zh_CN/service.ts b/bigtop-manager-ui/src/locales/zh_CN/service.ts index 3070cf2b..dee4c8a2 100644 --- a/bigtop-manager-ui/src/locales/zh_CN/service.ts +++ b/bigtop-manager-ui/src/locales/zh_CN/service.ts @@ -37,5 +37,6 @@ export default { summary: '总览', config: '配置', components: '组件', - quicklinks: '快速链接' + quick_links: '快速链接', + no_link: '无' } diff --git a/bigtop-manager-ui/src/pages/service/index.vue b/bigtop-manager-ui/src/pages/service/index.vue index 3563bafa..eb8db0ad 100644 --- a/bigtop-manager-ui/src/pages/service/index.vue +++ b/bigtop-manager-ui/src/pages/service/index.vue @@ -18,7 +18,7 @@ -->